Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copied image saved with different pixels to original with PIL

I need to make a copy of an image to manipulate it, however saving the original image and opening up the copied one seems to differ in their pixel values:

from PIL import Image

# Open original image
img = Image.open("mountain.jpg")
data = img.load()

# Display individual pixels
print("Pixel 1: {}".format(data[0,0]))
print("Pixel 2: {}".format(data[0,1]))
print("Pixel 3: {}".format(data[0,2]))

# Makes a copy of the input image and loads the copied image's pixel map
copyImage = img.copy()

copyImage.save('copy.jpg')
copyImage.close()

# Opens the copied image that was saved earlier and its pixel map
copy = Image.open("copy.jpg")
copy_data = copy.load()

print()

# Display copied images' individual pixels
print("Pixel 1 (copy): {}".format(copy_data[0,0]))
print("Pixel 2 (copy): {}".format(copy_data[0,1]))
print("Pixel 3 (copy): {}".format(copy_data[0,2]))

copy.close()

This outputs as:

Pixel 1: (72, 102, 112)
Pixel 2: (75, 105, 115)
Pixel 3: (71, 101, 111)

Pixel 1 (copy): (70, 100, 110)
Pixel 2 (copy): (77, 107, 117)
Pixel 3 (copy): (74, 104, 114)

Initially, I thought PIL might be changing all pixel values by 2 values for each of the R, G, and B channels (as can be seen with the first two pixels), however the third pixel has a change of 3 values to each channel.

How can I make a reliable copy of the image, in order to change its pixels, where the starting pixels of the copied image are the same as its original?

NOTE: I have tried other images other than my 'mountain.jpg', but all seem to be causing the same issues.

like image 881
Suraj Kothari Avatar asked Oct 26 '25 04:10

Suraj Kothari


2 Answers

*.jpg is a compressed image format. By saving the jpg again you use a different default quality for the jpg writer so the resulting pixel-values differ.

See image file format params for jpg for the quality parameter that you can pass to image.save()

quality
The image quality, on a scale from 1 (worst) to 95 (best). The default is 75. Values above 95 should be avoided; 100 disables portions of the JPEG compression algorithm, and results in large files with hardly any gain in image quality.

Either

  • move to a non-compressive format (png f.e.) or
  • copy the file using file operations: see f.e. How do I copy a file in Python?

Related:

  • Why is the quality of JPEG images produced by PIL so poor?
like image 176
Patrick Artner Avatar answered Oct 28 '25 22:10

Patrick Artner


The problem is saving image as JPG. Try to do it with PNG. By saving your image as JPG, you are doing JPG compression. That alters the pixels. Do this

copyImage.save('copy.png')
copyImage.close()

and

copy = Image.open("copy.png")
copy_data = copy.load()

NOTE:

You may want to see difference between JPG and PNG.

JPG is compression with cost of losing data

PNG is compression without loss of data

JPG will result in having very low size image but everytime you save the image, you are basicly compressing it again and again. The quality in general is low

PNG will result in quite big size, but saving and loading image will not result in any pixel change.

like image 28
Martin Avatar answered Oct 28 '25 22:10

Martin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!