Convert bytes to image Python OpenCV

Conceptually, a byte is an integer ranging from 0 to 255. In all real-time graphic applications today, a pixel is typically represented by one byte per channel, though other representations are also possible.

An OpenCV image is a 2D or 3D array of the .array type. An 8-bit grayscale image is a 2D array containing byte values. A 24-bit BGR image is a 3D array, which also contains byte values. We may access these values by using an expression, such as image[0, 0] or image[0, 0, 0]. The first index is the pixel’s y coordinate or row, 0 being the top. The second index is the pixel’s x coordinate or column, 0 being the leftmost. The third index (if applicable) represents a color channel.

For example, in an 8-bit grayscale image with a white pixel in the upper-left corner, image[0, 0] is 255. For a 24-bit BGR image with a blue pixel in the upper-left corner, image[0, 0] is [255, 0, 0].

As an alternative to using an expression, such as image[0, 0] or image[0, 0] = 128, we may use an expression, such as image.item((0, 0)) or image.setitem((0, 0), 128). The latter expressions are more efficient for single-pixel operations. However, as we will see in subsequent chapters, we usually want to perform operations on large slices of an image rather than on single pixels.

Provided that an image has 8 bits per channel, we can cast it to a standard Python bytearray, which is one-dimensional:

byteArray = bytearray(image)

Conversely, provided that bytearray contains bytes in an appropriate order, we can cast and then reshape it to get a numpy.array type that is an image:

# Convert Gray Byte array to Gray image's dimension
grayImage = numpy.array( grayByteArray).reshape(height, width)

# Convert RBG Byte array to color image's dimension
bgrImage = numpy.array( bgrByteArray).reshape(height, width, 3)

Here 3 in reshape refers to 3rd dimension which contains color for that pixel.

As a more complete example, let’s convert bytearray, which contains random bytes to a grayscale image and a BGR image:

# Import Necessary libraries.
import cv2
import numpy
import os

# Make an array of 120,000 random bytes.
randomByteArray = bytearray(os.urandom(120000))
flatNumpyArray = numpy.array(randomByteArray)

# Convert the array to make a 400x300 grayscale image.
grayImage = flatNumpyArray.reshape(300, 400)
cv2.imwrite('RandomGray.png', grayImage)

# Convert the array to make a 400x100 color image.
grayImage = numpy.array( grayByteArray).reshape(height, width)0)
grayImage = numpy.array( grayByteArray).reshape(height, width)1

After running this script, we should have a pair of randomly generated images, RandomGray.png and RandomColor.png, in the script’s directory.

Conceptually, a byte is an integer ranging from 0 to 255. Throughout real-time graphic applications today, a pixel is typically represented by one byte per channel, though other representations are also possible.

An OpenCV image is a 2D or 3D array of the numpy.array type. An 8-bit grayscale image is a 2D array containing byte values. A 24-bit BGR image is a 3D array, which also contains byte values. We may access these values by using an expression such as image[0, 0] or image[0, 0, 0]. The first index is the pixel's y coordinate or row, 0 being the top. The second index is the pixel's x coordinate or column, 0 being the leftmost. The third index (if applicable) represents a color channel. The array's ...

Sometimes, we may want an in-memory jpg or png image that is represented as binary data. But often, what we have got is image in OpenCV (Numpy ndarray) or PIL Image format. In this post, I will share how to convert Numpy image or PIL Image object to binary data without saving the underlying image to disk.

If the image file is saved on disk, we can read it directly in binary format with open() method by using the b flag:

with open('test.jpg', 'rb') as f:
    byte_im = f.read()

Now the image will be read from disk to memory and is still in binary format.

What if we want to resize the original image and convert it to binary data, without saving the resized image and re-read it from the hard disk? How should we do it?

Convert image to bytes

We can do it with the help of OpenCV or PIL.

OpenCV

This is how to achieve that in OpenCV:

import cv2

im = cv2.imread('test.jpg')
im_resize = cv2.resize(im, (500, 500))

is_success, im_buf_arr = cv2.imencode(".jpg", im_resize)
byte_im = im_buf_arr.tobytes()

# or using BytesIO
# io_buf = io.BytesIO(im_buf_arr)
# byte_im = io_buf.getvalue()

A little explanation here. will encode the Numpy ndarray in the specified format. This method will return two values, the first is whether the operation is successful, and the second is the encoded image in a one-dimension Numpy array.

Then you can convert the returned array to real bytes either with the tobytes() method or . We can finally get the byte_im. It is the same with saving the resized image in hard disk and then reading it in binary format, but the saving step is removed and all the operation is done in memory.

PIL

If you like to use PIL for image processing. You can use the following code:

import io
from PIL import Image

im = Image.open('test.jpg')
im_resize = im.resize((500, 500))
buf = io.BytesIO()
im_resize.save(buf, format='JPEG')
byte_im = buf.getvalue()

In the above code, we save the im_resize Image object into

import cv2

im = cv2.imread('test.jpg')
im_resize = cv2.resize(im, (500, 500))

is_success, im_buf_arr = cv2.imencode(".jpg", im_resize)
byte_im = im_buf_arr.tobytes()

# or using BytesIO
# io_buf = io.BytesIO(im_buf_arr)
# byte_im = io_buf.getvalue()
0 object
import cv2

im = cv2.imread('test.jpg')
im_resize = cv2.resize(im, (500, 500))

is_success, im_buf_arr = cv2.imencode(".jpg", im_resize)
byte_im = im_buf_arr.tobytes()

# or using BytesIO
# io_buf = io.BytesIO(im_buf_arr)
# byte_im = io_buf.getvalue()
1. Note that in this case, you have to specify the saving because PIL does not know the image format in this case. The bytes string can be retrieved using
import cv2

im = cv2.imread('test.jpg')
im_resize = cv2.resize(im, (500, 500))

is_success, im_buf_arr = cv2.imencode(".jpg", im_resize)
byte_im = im_buf_arr.tobytes()

# or using BytesIO
# io_buf = io.BytesIO(im_buf_arr)
# byte_im = io_buf.getvalue()
2 method of
import cv2

im = cv2.imread('test.jpg')
im_resize = cv2.resize(im, (500, 500))

is_success, im_buf_arr = cv2.imencode(".jpg", im_resize)
byte_im = im_buf_arr.tobytes()

# or using BytesIO
# io_buf = io.BytesIO(im_buf_arr)
# byte_im = io_buf.getvalue()
1 variable.

How do I create an image from bytes in Python?

Image. frombytes() Creates a copy of an image memory from pixel data in a buffer. In its simplest form, this function takes three arguments (mode, size, and unpacked pixel data).

How do I convert bytes to images?

To convert a byte array to an image..
Create a ByteArrayInputStream object by passing the byte array (that is to be converted) to its constructor..
Read the image using the read() method of the ImageIO class (by passing the ByteArrayInputStream objects to it as a parameter)..

How to read image as bytes in Python?

Syntax: Image.tobytes(encoder_name='raw', *args).
Parameters:.
encoder_name – What encoder to use. The default is to use the standard “raw” encoder. args – Extra arguments to the encoder..
Returns: A bytes object..

How do I convert bytes to string in Python?

Different ways to convert Bytes to string in Python:.
Using decode() method..
Using str() function..
Using codecs. decode() method..
Using map() without using the b prefix..
Using pandas to convert bytes to strings..