简体   繁体   中英

Image manipulation in Python using PIL and facing problem with fromarray()

I am writing a script to encrypt and decrypt an image in python3 using PIL. Here I am converting the image into a numpy array and then multiplying every element of the array with 10. Now I noticed that the default function in PIL fromarray() is converting every element of the array to the mod of 256 if its larger than the 255, so when I am trying to retrieve the original value of the matrix I'm not getting the original one. For example, if the original value is 40 then its 10 times is 400 so the fromarray() is making it as 400 mod 256, which will give 144. Now if I add 256 to 144 I will have 400 and then divided by 10 will give me 40. But if the value is 54 then 10times is 540 and 540 mod 256 is 28. Now to get back the original value I need to add 256 two times which will give me 540. 540 isn't the only number which will give me 28 when I will mod it with 256. So I will never know when to add 256 one time and when two times or more.

Heres the code:

from PIL import Image
from numpy import * 
from pylab import * 

#encryption

img1 = (Image.open('image.jpeg').convert('L')) 
img1.show() #displaying the image

img = array(Image.open('image.jpeg').convert('L'))
a,b = img.shape
print(img)
print((a,b))
tup = a,b

for i in range (0, tup[0]):
    for j in range (0, tup[1]):
        img[i][j]= img[i][j]*10 #converting every element of the original array to its 10times

print(img)
imgOut = Image.fromarray(img)
imgOut.show()
imgOut.save('img.jpeg')

#decryption

img2 = (Image.open('img.jpeg'))
img2.show()

img3 = array(Image.open('img.jpeg'))
print(img3)
a1,b1 = img3.shape
print((a1,b1))
tup1 = a1,b1

for i1 in range (0, tup1[0]):
    for j1 in range (0, tup1[1]):
        img3[i1][j1]= ((img3[i1][j1])/10) #reverse of encryption
print(img3)
imgOut1 = Image.fromarray(img3)
imgOut1.show()

Now as the function making its elements mod of 256 I am unable to get back the original value from the mod value. How can i get the original value.Is there any other methods to convert matrix to image and vice versa which, will not make it mod of any number by default.

Now I do not know how to deal with this problem. Any help will be greatly appreciated.Thank you.

This is not the right way to do it. There is no way that you can have the actual value. After the values are changed to its mod of 256 you cannot get the previous value back. As you are reading the image as 8bit depth JPEG you cannot have a value more than 255 in the numpy array , as we need more than 8bits to store a value that is more than 255 in decimal number system. So what you can do is that you can read the image as 8bit depth image and then convert the numpy.ndarray of the image to 16bit or 32bit as you want. You can do that by using img_array.astype(numpy.uint16) Or img_array.astype(numpy.uint32) You can check the type by using print(img_array.dtype()) If you convert the numpy array to uint16 then the largest value you can have in the array is 2^16-1 and for uint32 it is 2^32-1 .

Now you can save the array using imageio which can read the write the image as 16bit depth.

`import imageio as io
 img_array = io.imread('16bit.png')
 io.imwrite('new16bit.png', img_array)`

Use .png as its lossless and can store 16bit datas. PIL will always convert the 16bit or 32bit to 8bit numpy array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM