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()
1 Answer 1
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()
-
\$\begingroup\$ Thank you very much. Greatly appreciate your feedback. \$\endgroup\$Uncle Bob– Uncle Bob2020年08月17日 06:01:29 +00:00Commented Aug 17, 2020 at 6:01