3
\$\begingroup\$

Please review and help me write better codes.

Combining Pictures We can use a conditional to copy just the non-white pixels from one picture to another picture. We can take this tiny image of the women and put her by the Eiffel tower in Paris, France. I have modified the code so that the code automatically swaps the image1 and image2; hence, always using the larger image as the canvas and the smaller picture as the insert.

from PIL import Image

image1 = Image.open("lady_tiny.jpg")
image2 = Image.open("eiffel.jpg")

width = min(image1.size[0], image2.size[0])  # (x)
length = min(image1.size[1], image2.size[1])  # (y)
    
# check if smaller image then use it as insert
if width == image2.size[0] and length == image2.size[1]:
    canvas = image1.load()  # larger pic
    insert = image2.load()  # smaller pic
else:
    insert = image1.load()
    canvas = image2.load()

for col in range(width):  
    for row in range(length):
        r, g, b = insert[col, row]  # read each pixel of insert(small)
    
        # Check if the pixel isn't white
        if r < 250 and g< 250 and b< 250:
            # Copy the color of insert (smaller) onto the canvas(larger)
            canvas[col, row + 130] = r, g, b

if (
    width == image2.size[0] and length == image2.size[1]
):  # if image2 is insert then image 1 is canvas
    image1.show()
else:
    image2.show()
\$\endgroup\$
3
\$\begingroup\$

You can simplify the checks that find the smallest image. If you assume that if the image is smaller in one dimension, it will be smaller in both (which you seem to be already), you can find the smallest image using min's key parameter:

small_image = min(image1, image2, key=lambda image: image.size[0])
large_image = image1 if image2 == small_image else image2

canvas = large_image.load()
insert = small_image.load()

The key function is applied to each image before they're compared. In this case, I'm comparing each of the image's size[0] values. To get the larger image, you could get creative with sets if images are hashable, but I think a conditional expression is probably easiest.

This also reduces your check at the bottom to just

large_image.show()

This part:

r, g, b = insert[col, row]

if r < 250 and g< 250 and b< 250:
        canvas[col, row + 130] = r, g, b

Can be simplified a bit if you use all with a generator expression:

color = insert[col, row]

if all(c < 250 for c in color):
    canvas[col, row + 130] = color

This frees you up from needing to create, compare, then recombine three separate variables.


Final code:

from PIL import Image

image1 = Image.open("lady_tiny.jpg")
image2 = Image.open("eiffel.jpg")

small_image = min(image1, image2, key=lambda image: image.size[0])
large_image = image1 if image2 == small_image else image2

canvas = large_image.load()
insert = small_image.load()

for col in range(width):
    for row in range(length):
        color = insert[col, row]

        if all(c < 250 for c in color):
            canvas[col, row + 130] = color
            
large_image.show()
\$\endgroup\$
1
  • \$\begingroup\$ Thank you very much. Greatly appreciate your feedback. \$\endgroup\$
    – Uncle Bob
    Aug 17 '20 at 6:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.