简体   繁体   中英

Conversion 2-dimensional rgb matrix to PNG Image with Python 3.6

I need to convert a 2-dimensional 24bit rgb- matrix with Python 3.6

[[rr11gg11bb11, rr12gg12bb12,..  ..,rr1mgg1mbb1m],
.
.
 [rri1gg11bb11, rr12ggi2bb12,..  ..,rr1mgg1mbb1m]
.
.
 [rrn1ggn1bbn1, rrn2ggn2bbn2,.. ..,rrmnggmnbbmn]]

into an image of the format tif, png and jpg.

I've also got the matrix in form of a file

image.bin.

From this binary file I can whatch the image with the help of a RAW Pixel Viewer:

http://rawpixels.net/ 

I have found the PIL library, but I didn't find any method to build an image object out of these data. How can I do that? I use Python 3.6.

Now I've tried the following:

im = Image.frombuffer('RGB', (self.width, self.height), self.matrix, 'raw', 
'RGB', 0, 1)              
logger.info("image object created.")
im.save('result.png')
logger.info("image saved as result.png")

But I get the message:

TypeError: a bytes-like object is required, not 'list'

Now I've found out that I must convert the object into a bytearray:

 npm = np.array(self.matrix)
 arr = bytearray(npm)
 print(arr)
 im = Image.frombuffer('RGB', (self.width, self.height), arr, 'raw', 
'RGB', 0, 1)        

The conversion just works, when I use 'L', or 'RGBA', but not with 'RGB'. Strangely in this case it refuses a bytearray object.

Updated Answer

So, essentially, you don't have a Numpy array, but you have a list of lists wherein each element is a single 24-bit number that represents an RGB triplet RGB888.

So, I can make a representation of your list like this:

f=[ 
[0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF],
[0xFFFFFF,0xFFFFFF,0xFFFFFF,0x000000,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF],
[0xFFFFFF,0xFFFFFF,0x000000,0xFFFFFF,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF],
[0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF],
[0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF]
] 

So, I can make that into a Numpy array of uint32 elements like this:

na = np.array(f).astype(np.uint32) 

And then make an RGB array that PIL will like using:

h,w = 5,10
RGB=np.zeros((h,w,3),dtype=np.uint8)

Then I just have to shift and copy the triplets into the right places:

RGB[:,:,0] = na>>16            # Take red from top
RGB[:,:,1] = (na>>8) & 0xff    # Take green from middle
RGB[:,:,2] = na & 0xff         # Take blue from bottom

Now I can make a PIL image from that RGB array and save it to disk:

pIm = Image.fromarray(RGB).save('result.png')

Original Answer

Let's create a file of test data with ImageMagick . First as a PNG, just so you can see it:

magick -size 640x480 gradient:magenta-yellow image.png

在此处输入图像描述

And now the same thing again, but this time as RGB888 to match your file:

magick -size 640x480 gradient:magenta-yellow -depth 8 rgb:image.bin

Now:

from PIL import Image

# Open the file and read contents into "data"
with open('image.bin','rb') as f: 
    data = f.read() 

# Convert that into PIL Image
im = Image.frombuffer('RGB', (640, 480), data, 'raw', 'RGB', 0, 1)

# Save
im.save('result.png')

You could equally let Numpy read the file and then convert the result to a PIL Image:

import numpy as np

im = Image.fromarray(np.fromfile('image.bin',dtype=np.uint8).reshape(480,640,3))

If you want to check your binary file actually contains what you think it contains, you can also convert it to a PNG with ImageMagick to test it. Say you think the file is 640 pixels wide by 480 pixels tall and RGB888, you can ask ImageMagick to make it into a PNG with:

magick -depth 8 -size 640x480 RGB:<YOURFILENAME> image.png

Or, if you think it is a single 16-bit, single channel greyscale image with a 128 byte header that you want to ignore:

magick -depth 16 -size 640x480+128 GRAY:<YOURFILENAME> image.png

Keywords : Raw, raw image, binary file, image, image processing, Python, ImageMagick, convert.

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