131

I have an image in PIL Image format. I need to convert it to byte array.

img = Image.open(fh, mode='r')  
roiImg = img.crop(box)

Now I need the roiImg as a byte array.

martineau
  • 119,623
  • 25
  • 170
  • 301
Evelyn Jeba
  • 4,181
  • 3
  • 12
  • 10
  • 2
    Please supply more detail. In what format is the byte array supposed to be? The raw pixels values are available via `Image.getdata()`, which returns the internal representation PIL uses for an image in a particular format on a particular platform. – dhke Oct 13 '15 at 11:57
  • Not sure, but it sounds like you need to use the`Image`'s [`getdata()`](http://pillow.readthedocs.org/en/3.0.x/reference/Image.html#PIL.Image.Image.getdata) method. – martineau Oct 13 '15 at 12:08
  • My objective is to save the image in mysql database as a BLOB type. – Evelyn Jeba Oct 13 '15 at 12:30
  • `imgByteArr = open("foo.png" 'rb').read()` Need `roiImg` in the same format as `imgByteArr` – Evelyn Jeba Oct 13 '15 at 12:56

4 Answers4

284

Thanks everyone for your help.

Finally got it resolved!!

import io
from PIL import Image

img = Image.open(fh, mode='r')
roi_img = img.crop(box)

img_byte_arr = io.BytesIO()
roi_img.save(img_byte_arr, format='PNG')
img_byte_arr = img_byte_arr.getvalue()

With this i don't have to save the cropped image in my hard disc and I'm able to retrieve the byte array from a PIL cropped image.

patelnisheet
  • 124
  • 1
  • 3
  • 12
Evelyn Jeba
  • 4,181
  • 3
  • 12
  • 10
59

This is my solution:

from PIL import Image
import io

def image_to_byte_array(image: Image) -> bytes:
  # BytesIO is a file-like buffer stored in memory
  imgByteArr = io.BytesIO()
  # image.save expects a file-like as a argument
  image.save(imgByteArr, format=image.format)
  # Turn the BytesIO object back into a bytes object
  imgByteArr = imgByteArr.getvalue()
  return imgByteArr
bfontaine
  • 18,169
  • 13
  • 73
  • 107
Nori
  • 2,340
  • 1
  • 18
  • 41
7

I think you can simply call the PIL image's .tobytes() method, and from there, to convert it to an array, use the bytes built-in.

#assuming image is a flattened, 3-channel numpy array of e.g. 600 x 600 pixels
bytesarray = bytes(Image.fromarray(array.reshape((600,600,3))).tobytes())
Chris Ivan
  • 477
  • 5
  • 13
  • 9
    From documentation https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.tobytes it is not recomended, as it save raw image data for each pixel. If you use PNG, JPG, e.t.c. then need to use BytesIO() in Image.save() – XCanG Feb 22 '20 at 13:28
  • Ah, I see. For my purposes, I didn't need the bytes data, since I immediately do numerical processing on the RBG values. Also, the question doesn't mention anything about saving the images, only converting them. Consider removing your down vote for that reason. – Chris Ivan Jun 08 '20 at 02:08
-4

Python file read and extract binary array

import base64
with open(img_file_name, "rb") as f:
    image_binary = f.read()
    base64_encode = base64.b64encode(image_binary)
    byte_decode = base64_encode.decode('utf8')
DuDa
  • 3,718
  • 4
  • 16
  • 36