简体   繁体   中英

Convert a image (png and jpg) to a multi-dimensional list and backwards in python

I use PIL in order to convert imagse to monochrome and afterwards to a list of lists, but I am not sure how to do so with rgb images.

Can someone give me a direction how to convert images to a multi-dimensional list and backwards an python?

Let's start with a known sample image. Here's a small 3x2 one to actually work with and a larger one just so you can see it:

Small:

在此输入图像描述

Large:

在此输入图像描述

You can open an image and make it into an efficient, fast numpy multi-dimensional array like this:

#!/usr/local/bin/python3
import numpy as np
from PIL import Image

# Open image from disk
im = Image.open('image.png')
na = np.array(im)

That will look like this:

array([[[255,   0,   0],                      # Red
        [  0, 255,   0],                      # Green
        [  0,   0, 255]],                     # Blue

       [[  0,   0,   0],                      # Black
        [255, 255, 255],                      # White
        [126, 126, 126]]], dtype=uint8)       # Mid-grey

And convert it back to a PIL Image and save like this (just append this code to the code above):

# Convert array back to Image
resultim = Image.fromarray(na)
resultim.save('result.png')

Some notes :

Note 1

If you expect and want an RGB888 image, and you are opening a PNG image, you may get a palettised image which doesn't have RGB values for each pixel, but instead has an index into a palette for each pixel and everything will go wrong!

By way of example, here is the same image as above but when the generating application saved it as a palettised image:

array([[0, 1, 2],
       [3, 4, 5]], dtype=uint8)

And here what is returned from im.getpalette() :

[255,
 0,
 0,
 0,
 255,
 0,
 0,
 0,
 255,
 0,
 0,
 0,
 255,
 255,
 255,
 126,
 126,
 126,
 ...
 ...

So, the moral of the story is... if you are expecting an RGB888 image, use:

Image.open('image.png').convert('RGB')

Note 2

Likewise, if you open a PNG file that contains transparency, it will have 4 channels, the last being alpha/transparency, and you should call convert('RGB') if you wish to discard the alpha channel.

Note 3

You can abbreviate the loading and saving into single lines if you don't want the intermediate image:

# Load and make array in one go
na = np.array(Image.open('image.png').convert('RGB'))

# Convert back to PIL Image and save in one go
Image.fromarray(na).save('result.png')

Keywords : Image, image processing, numpy, array, ndarray, PIL, Pillow, Python, Python3, palette, PNG, JPG

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