Search code examples
pythonpython-imaging-librarypixel

Python Imaging Library corrupts the pixel data


I have a jpg image, using PIL I am obtaining the pixel data of the image, making some changes (cyclically permuting the RGB values) for certain pixels (leaving the other pixels untouched) and then saving it as a new image. However it seems that the data of the other pixels is getting changed? What is the problem? Here is the code attached

import numpy as np
import Image as img


def NumOcurr(DigArray,i):
    val = DigArray[i]
    count=0
    for j in np.arange(i):
        if (DigArray[j]==val):
            count=count+1
    return count        

def CycPermuteR(A):
    t1 = A[0]
    t2 = A[1]
    t3 = A[2]
    A[0] = t3
    A[1] = t1
    A[2] = t2
    return A
##################################
### put the number in an array ###
##################################
number = np.loadtxt("C:\Users\Sthitadhi Roy\Documents\Pixel Data Encryption\Number.txt")
DigArray = np.zeros(16)

for i in np.arange(16):
    DigArray[-1-i] = number%10
    number = int(number/10)

print DigArray

##################################
## Pixel Data for original #######
##################################    
OrigImg = img.open("C:\Users\Sthitadhi Roy\Documents\Pixel Data Encryption\Nondescript.jpg")             
PixelData = OrigImg.load()
print PixelData[0,0]
#################################
## Change Pixel Data ############
#################################
for i in range(16):
    TempPixelData = PixelData[i,DigArray[i]]
    TempPixelData = np.array(TempPixelData)
    TPD = TempPixelData.copy()
    CycPermuteR(TPD)
    PixelData[i,DigArray[i]] = (TPD[0],TPD[1],TPD[2])

print PixelData[0,0]    
OrigImg.save("C:\Users\Sthitadhi Roy\Documents\Pixel Data Encryption\Modified.jpg")   

NewImg = img.open("C:\Users\Sthitadhi Roy\Documents\Pixel Data Encryption\Modified.jpg")             
PixelDataN = NewImg.load()
print PixelDataN[0,0]

Here is the output

[ 5.  2.  3.  6.  4.  5.  8.  7.  4.  5.  8.  3.  1.  2.  4.  8.]
(148, 136, 98)
(148, 136, 98)
(146, 137, 108)

As you can see the 0th element of DigArray is 5, so it should leave the [0,0] pixel unchanged. The operation that is use to change the pixel data is correct because it also leave it unchanged as shown by the third line of the output. But after I save it as a new image and then again reload it [0,0] pixel does not have the same data anymore.

Why is this happening and how can it be solved?


Solution

  • You are saving the image in JPEG format, which is a compressed and lossy format.

    Try saving the image as PNG, which is a lossless format.

    import os
    imagedir = "C:\Users\Sthitadhi Roy\Documents\Pixel Data Encryption"
    
    OrigImg.save(os.path.join(imagedir, "Modified.jpg"))