someuser2491
someuser2491

Reputation: 1968

How to compare two image files contents in python?

I want to compare two image files (.png) basically reading two .png files and assert if the contents are equal.

I have tried below,

def read_file_contents(file1, file2):
     with open(file1, 'r', errors='ignore') as f:
        contents1 = f.readlines()
        f.close()
     with open(file1, 'r', errors='ignore') as f:
        contents2 = f.readlines()
        f.close()
     return {contents1, contents2}

then to assert if both the contents are equal I use

 assert contents1 == contents2

but this gives me assertionerror. could someone help me with this. thanks.

Upvotes: 2

Views: 6628

Answers (3)

Yoel Nisanov
Yoel Nisanov

Reputation: 1054

I don't think using selenium as a tag here is a right choice but w/e.

Images can and are represented as bunch of pixels (basically numbers) arranged in such way that makes them what they are. The idea is to take those numbers with their arrangement of both pictures and calculate the distance between them, there are multiple ways to do so like MSE. For the code it self and a further explanation please check out the link below.

https://www.pyimagesearch.com/2014/09/15/python-compare-two-images/

Good luck buddy! (:

Upvotes: 0

Life is complex
Life is complex

Reputation: 15619

There are multiple ways to accomplish this task using various Python libraries, including numpy & math, imagehash and pillow.

Here is one way (which I modified to only compare 2 images).

# This module is used to load images
from PIL import Image
# This module contains a number of arithmetical image operations
from PIL import ImageChops

def image_pixel_differences(base_image, compare_image):
  """
  Calculates the bounding box of the non-zero regions in the image.
  :param base_image: target image to find
  :param compare_image:  set of images containing the target image
  :return: The bounding box is returned as a 4-tuple defining the
           left, upper, right, and lower pixel coordinate. If the image
           is completely empty, this method returns None.
  """
  # Returns the absolute value of the pixel-by-pixel
  # difference between two images.

  diff = ImageChops.difference(base_image, compare_image)
  if diff.getbbox():
    return False
  else:
    return True

base_image = Image.open('image01.jpeg')
compare_image = Image.open('image02.jpeg')
results = image_pixel_differences (base_image, compare_image)

I have additional examples, so please let me know if this one does not work for you.

Upvotes: 5

r.ook
r.ook

Reputation: 13868

If you just want an exact match, you can compare the bytes directly:

def validate_file_contents(file1, file2):
    with open(file1, 'rb', errors='ignore') as f1, open(file2, 'rb', errors='ignore') as f2:
        contents1 = f1.read()
        contents2 = f2.read()
    return contents1 == contents2     

You could use an assert if you want, but personally I'd check the True/False condition instead.

You also had a few errors in your code:

  1. The content within the with block is not indented.
  2. In a with block you don't need to close() the files.
  3. You are returning a set of content1 and content2, where if they are actually equal, you will only have 1 item returned. You probably wanted to return (content1, content2) as a tuple.

Upvotes: 3

Related Questions