1# Copyright (c) 2011 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Compare two images for equality, subject to a mask."""
6
7from PIL import Image
8from PIL import ImageChops
9
10import os.path
11
12
13def Compare(file1, file2, **kwargs):
14  """Compares two images to see if they're identical subject to a mask.
15
16  An optional directory containing masks is supplied. If a mask exists
17  which matches file1's name, areas under the mask where it's black
18  are ignored.
19
20  Args:
21    file1: path to first image to compare
22    file2: path to second image to compare
23    kwargs: ["maskdir"] contains the directory holding the masks
24
25  Returns:
26    None if the images are identical
27    A tuple of (errorstring, image) if they're not
28  """
29
30  maskdir = None
31  if "maskdir" in kwargs:
32    maskdir = kwargs["maskdir"]
33
34  im1 = Image.open(file1)
35  im2 = Image.open(file2)
36
37  if im1.size != im2.size:
38    return ("The images are of different size (%r vs %r)" %
39            (im1.size, im2.size), im1)
40
41  diff = ImageChops.difference(im1, im2)
42
43  if maskdir:
44    maskfile = os.path.join(maskdir, os.path.basename(file1))
45    if os.path.exists(maskfile):
46      mask = Image.open(maskfile)
47
48      if mask.size != im1.size:
49        return ("The mask is of a different size than the images (%r vs %r)" %
50                (mask.size, im1.size), mask)
51
52      diff = ImageChops.multiply(diff, mask.convert(diff.mode))
53
54  if max(diff.getextrema()) != (0, 0):
55    return ("The images differ", diff)
56  else:
57    return None
58