0

I am trying to develop an application which upload an image by using some Javascript codes. The Javascript code return me an array with the size equal to its size. so if I have a 4k size jpg image, it returns to me (approximate) 4,000 bytes of image data with the type of unit8. It is a python list like below.

[137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 50, 0, 0, 0, 50, 8, 6, 0, 0, 0, 30, 63, 136, 177, 0, 0, 0, 1, 115, 82, 71, 66, 1, 217, 201, 44, 127, 0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 11,
19, 0, 0, 11, 19, 1, 0, 154, 156, 24, 0, 0, 12, 76, 73, 68, 65, 84, 120, 156, 205, 90, 9, 116, 84, 85, 18, 125, 85, 191, 155, 69, 136, 6, 81, 143, 204, 184, 224, 130, 251, 58, 234, 168, 227, 56, 42, 46, 99, 0, 145
, 221, 153, 1, 68, 22, 9, 4, 18, 72, 128, 132, 64, 22, 146, 16, 18, 8, 4, 8, 73, 200, 0, 178, 4, 68, 86, 89, 195, 190, 139, 130, 65, 16, 5, 113, 1, 4, 21, 20, 16, 81, 32, 64, 72, 250, 85, 205, 253, 29, 228, 140, 1
03, 28, 108, 9, 33, 212, 57, 117, 222, 79, 247, 239, 247, 235, 190, 170, 186, 85, 245, 193, 152, 75, 64, 236, 60, 67, 190, 5, 166, 186, 46, 50, 84, 174, 141, 36, 147, 59, 74, 180, 39, 167, 180, 11, 229, 74, 123, 2
06, 181, 221, 157, 116, 219, 143, 250, 105, 154, 19, 103, 211, 169, 124, 155, 159, 235, 185, 83, 13, 233, 108, 122, 192, 206, 50, 233, 50, 139, 18, 101, 9, 215, 214, 105...]

Now I have above byte array, I would like to know how to read above array in OpenCV or by using Numpy?

I have written some codes by imdecode and imread but none of them work properly.

import cv2
img = cv2.imdecode(np.asarray(image_array), cv2.IMREAD_UNCHANGED)

The above codes always return me null images. Is this possible to read an image in OpenCV by using above array?

2
  • numpy arrays can be directly manipulated by cv2, cv2 images are treated as numpy arrays in the backend. what does image_array look like? imdecode expects a bytestring last I remember Commented Sep 2, 2020 at 1:59
  • If you provide the whole list (Dropbox, Google Drive) and the height and width of the image it should be easy enough to work out. Commented Sep 2, 2020 at 6:47

2 Answers 2

1

If you look at the first few elements of your list, you will see it is classic PNG file signature (magic number), or, in hex:

89 50 4e 47 0d 0a 1a 0a

where 50 is ASCII P, 4e is ASCII N and 47 is G - spelling PNG. That means your Javascript has sent you a PNG-encoded image.

So, you need the following:

import cv2
import numpy as np

L = [137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 64, 0, 0, 0, 64, 8, 2, 0, 0, 0, 37, 11, 230, 137, 0, 0, 0, 4, 103, 65, 77, 65, 0, 0, 177, 143, 11, 252, 97, 5, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0, 122, 38, 0, 0, 128, 132, 0, 0, 250, 0, 0, 0, 128, 232, 0, 0, 117, 48, 0, 0, 234, 96, 0, 0, 58, 152, 0, 0, 23, 112, 156, 186, 81, 60, 0, 0, 0, 6, 98, 75, 71, 68, 0, 255, 0, 255, 0, 255, 160, 189, 167, 147, 0, 0, 0, 7, 116, 73, 77, 69, 7, 228, 9, 3, 7, 16, 45, 84, 246, 102, 10, 0, 0, 0, 112, 73, 68, 65, 84, 104, 222, 237, 215, 177, 9, 192, 64, 12, 4, 65, 25, 222, 253, 151, 108, 23, 241, 193, 34, 152, 173, 224, 6, 69, 154, 89, 222, 115, 230, 212, 27, 174, 58, 0, 0, 0, 0, 0, 0, 155, 59, 239, 188, 245, 134, 59, 192, 250, 11, 0, 0, 0, 0, 0, 0, 108, 14, 160, 14, 160, 14, 160, 14, 160, 14, 160, 206, 83, 95, 7, 80, 7, 80, 7, 80, 7, 80, 7, 80, 7, 80, 7, 80, 7, 80, 7, 80, 183, 31, 224, 169, 7, 0, 0, 0, 0, 216, 220, 122, 192, 243, 205, 87, 111, 184, 234, 7, 229, 134, 4, 235, 125, 72, 121, 243, 0, 0, 0, 37, 116, 69, 88, 116, 100, 97, 116, 101, 58, 99, 114, 101, 97, 116, 101, 0, 50, 48, 50, 48, 45, 48, 57, 45, 48, 51, 84, 48, 55, 58, 49, 54, 58, 52, 53, 43, 48, 48, 58, 48, 48, 156, 134, 199, 95, 0, 0, 0, 37, 116, 69, 88, 116, 100, 97, 116, 101, 58, 109, 111, 100, 105, 102, 121, 0, 50, 48, 50, 48, 45, 48, 57, 45, 48, 51, 84, 48, 55, 58, 49, 54, 58, 52, 53, 43, 48, 48, 58, 48, 48, 237, 219, 127, 227, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130]

# Decode the PNG-encoded image
im = cv2.imdecode(np.array(L, dtype=np.uint8), cv2.IMREAD_UNCHANGED)

enter image description here


As you didn't provide your list, I did the following to replicate your starting position...

First, make a small PNG image with ImageMagick:

magick -size 64x64 gradient:black-magenta PNG24:a.png

Then, slurp all the bytes from the PNG-encoded file and make them into a list:

with open('a.png', 'rb') as image:
    data = image.read()
L = list(data)

Keywords: Python. image processing, OpenCV, decode, encoded, Javascript, image.

Sign up to request clarification or add additional context in comments.

2 Comments

whel, actally, that was not the original image which I intended, I have editted my question and put the javascript coes which I am using to send through the bytebuffer array.
How very annoying. Maybe you will consider doing as I asked yesterday in the comments and providing actual, complete data then please!
0

most likely javascript will give you image in base64. so you just need to first decode and then make it file like object to open with opencv

import base64
import numpy as np
import cv2

with open("test.jpg", "rb") as f:
    im_b64 = base64.b64encode(f.read())

im_bytes = base64.b64decode(im_b64)
im_arr = np.frombuffer(im_bytes, dtype=np.uint8)  # im_arr is one-dim Numpy array
img = cv2.imdecode(im_arr, flags=cv2.IMREAD_COLOR)

[EDIT]

on the javascript side. its easier to use base64 images and this is the example how its being done

this is the html chunk how im uploading file. just a regular input type

<input type="file" class="custom-file-input" name="image" id="image" onchange=saveimgs(this)
                multiple />

this is actual javascript that is making file into base64 img

function saveimgs(a) {
    Array.prototype.forEach.call(a.files, (img) => {
        var reader = new FileReader();
        reader.onload = function(e) {
            var base64img = e.target.result;
            imgs.push(base64img); //push base64 representation of the image to imgs array                
        };
        reader.readAsDataURL(img);
    });
}

after that you can send this array containing base64 images to python with json

6 Comments

This doesnt answer my question, I am getting a list of unit8 type values, so how to convert my list to a numpy array or openCV images?
my bad. i thought you wanted to display utf8 representation of the image with opencv. im not sure but never heard about "unit8". could you please provide one example?
Hi, in above codes image_array is a python list. I should create opencv image from that list, not sure if it is possible or not?
depens about what does your list contains. for example if list just contain fruit names you cant make an image but if it contains rgb values than you certainly can. looks like its rgb values. just for quick note, is the len(your_list)%3==0?
Hi, len(your_list)%3!=0 for my samples, it is equal to the size of images, if it is 2k, it would have 2,000 elements.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.