pythonpython-imageio

Imageio.imwrite does not save the correct values


Can someone please explain why do I get this inconsistency in rgb values after saving the image.

import imageio as io

image = 'img.jpg'
type = image.split('.')[-1]
output = 'output' + type

img = io.imread(image)

print(img[0][0][1]) # 204

img[0][0][1] = 255

print(img[0][0][1]) # 255

io.imwrite(output, img, type, quality = 100)

imgTest = io.imread(output)

print(imgTest[0][0][1]) # 223

# io.help('jpg')

Image used = img.jpg


Solution

  • The reason that pixels are changed when loading a jpeg image and then saving it as a jpeg again is that jpeg uses lossy compression. To save storage space for jpeg images, pixel values are saved in a dimension-reduced representation. You can find some information about the specific algorithm here. The advantage of lossy compression is that the image size can significantly be reduced, without the human eye noticing any changes. However, without any additional methods, we will not retrieve the original image after saving it in jpg format.

    An alternative that does not use lossy compression is the png format, which we can verify by converting your example image to png and runnning the code again:

    import imageio as io
    import numpy as np
    import matplotlib.pyplot as plt
    
    image = '/content/drive/My Drive/img.png'
    type = image.split('.')[-1]
    output = 'output' + type
    
    img = io.imread(image)
    
    print(img[0][0][1]) # 204
    
    img[0][0][1] = 255
    
    print(img[0][0][1]) # 255
    
    io.imwrite(output, img, type)
    
    imgTest = io.imread(output)
    
    print(imgTest[0][0][1]) # 223
    
    # io.help('jpg')
    

    Output:

    204
    255
    255
    

    We can also see that the png image takes up much more storage space than the jpg image

    import os
    os.path.getsize('img.png')
    # output: 688444
    os.path.getsize('img.jpg')
    # output: 69621
    

    Here is the png image: png image