Home > other >  PIL doesn't detect identical images
PIL doesn't detect identical images

Time:04-09

I need to determine if an image layer (mainLayer) will be visible within a final image, in which it will be underneath layer, layer2 and layer3. I need to do this without knowing what those other layers are. All of these image layers are RGBA; they also have the same dimensions (2048x2048) and file format (.png).

Here's the code I have so far:

# Create compImage1, which is all of the layers that go on top of mainLayer
compImage1 = layer.copy()
compImage1.paste(layer2, (0, 0), layer2)
compImage1.paste(layer3, (0, 0), layer3)

# Create compImage2, which is mainLayer with all of the other layers added
compImage2 = mainLayer.copy() # I want to determine this layer's visibility in the final image
compImage1Copy = compImage1.copy()
compImage2.paste(compImage1Copy, (0, 0), compImage1Copy)

# Compare compImage1 and compImage2; if layer, layer2, and/or layer 3 completely obscure
# mainLayer, then there should be no difference between the two images    
difference = ImageChops.difference(
    compImage1.convert("RGB"), compImage2.convert("RGB")
).getbbox()

if not difference:
    print("mainLayer will not be visible")
else:
    print("mainLayer will be visible")

This code prints "mainLayer will be visible" when mainLayer is not covered by layer, layer2, and/or layer3. However, it still prints "mainLayer will be visible" when mainLayer is covered by one of those layers.

Why is this code not working correctly? Is there a better/faster way to do this? Thank you for any help you can provide.

EDIT: I was asked to clarify what exactly I'm asking:

I have 4 image layers: mainLayer, layer, layer2, and layer3. I am putting them together into one image. I do not know the positions or sizes of any of the visible portions of these layers; they are all 2048x2048 image layers, and most of each image layer is transparent.

I need to know if mainLayer will be completely covered by any combination of layer, layer2, and layer3 (case 2), or if it will not (case 1). My code works for case 1, but not case 2. enter image description here

It runs like this:

Base image bbox: (80, 800, 301, 951)
Loading layer0.png
Loading layer1.png
Loading layer2.png
Result: True

And if I use these images, the answer is False.

enter image description here


Note that I made the images with ImageMagick like this:

Case 1

#!/bin/bash
magick -size 2000x2000 xc:none -fill red  -draw "rectangle 80,800 300,950"    PNG32:base.png
magick -size 2000x2000 xc:none -fill blue -draw "rectangle 280,700 480,850"   PNG32:layer0.png  
magick -size 2000x2000 xc:none -fill lime -draw "rectangle 320,1000 460,1200" PNG32:layer1.png
magick -size 2000x2000 xc:none -fill orange -draw "rectangle 500,800 800,900" PNG32:layer2.png
magick base.png layer0.png -composite layer1.png -composite layer2.png -composite PNG32:case1.png

Case 2

#!/bin/bash
magick -size 2000x2000 xc:none -fill red  -draw "rectangle 80,800 300,950"    PNG32:base.png
magick -size 2000x2000 xc:none -fill blue -draw "rectangle 70,700 350,900"    PNG32:layer0.png  
magick -size 2000x2000 xc:none -fill lime -draw "rectangle 50,900 250,1200" PNG32:layer1.png
magick -size 2000x2000 xc:none -fill orange -draw "rectangle 250,900 800,1200" PNG32:layer2.png
magick base.png layer0.png -composite layer1.png -composite layer2.png -composite PNG32:case2.png

Note that if your base and/or layers contain partial transparency, and/or "holes", and/or discontiguous areas of transparency, and/or ragged edges, you will need to check carefully the DEBUG images my code produces to be sure I have covered all cases.

  • Related