3

I read an jpg image with python using pillow module:

from PIL import Image

img = Image.open('./test.jpg')
bytes = img.tobytes()

If I print bytes I get something like this:

print(f'{bytes}')
# b'\xbe\xb0i\xb1\xa4^\xb1\xaad\xab\xa7`\xc2\xc0v\x96\x91Oj_2\xb7...

I send then this 'bytes string' to my js to display it:

var b64imgData = btoa(bytes); // bytes is the 'bytes string' show upper
var img = new Image();
img.src = "data:image/jpg;base64," + b64imgData;

$('#imgCtn').append(img);

Sadly the final image source doesn't seem to be valid because I get the invalid image icon instead of my image test.jpg.

Has someone an idea where the issue is ?


EDIT 1:

As it is mentionned by @cubrr don't use img.tobytes() method for jpg files. So for the python code please use this one:

from PIL import Image

img = Image.open('./test.jpg')
imageBytes = io.BytesIO()
img.save(imageBytes, format='JPEG')
bytes = imageBytes.getvalue()
johannchopin
  • 13,720
  • 10
  • 55
  • 101
  • I’m voting to close this since, from the comments OP has made, there appear to be many distinct issues here. – AMC Jan 06 '20 at 23:34
  • @AMC Well I understand but in my opinion I will not be the only one to search to achieve this type of feature and there are not a lot of questions that raise it on SO. – johannchopin Jan 06 '20 at 23:40
  • 1
    In that case it might be better to edit your post to accurately reflect what you’re trying to do. – AMC Jan 06 '20 at 23:41

1 Answers1

1

From the documentation of Pillow:

Image.tobytes(encoder_name='raw', *args)

...

Warning: This method returns the raw image data from the internal storage. For compressed image data (e.g. PNG, JPEG) use save(), with a BytesIO parameter for in-memory data.

So try using save to get the JPG bytes instead of the raw internal image data:

img = Image.open('./test.jpg')
imageBytes = io.BytesIO()
img.save(imageBytes, format='JPEG')
bytes = imageBytes.getvalue()

If if still does not work, please elaborate on what you mean by "send this bytes string to my js". How are you sending and receiving it (code please)?

cbr
  • 12,563
  • 3
  • 38
  • 63
  • Ok Thanks but where does I have to specify my image name ? I use a websockets service to send it to my `js` – johannchopin Jan 06 '20 at 22:30
  • I'm not sure what you mean. Does it not work if you just send the `bytes` from my example just like you send the `bytes` from your own example? – cbr Jan 06 '20 at 22:32
  • I updated my example to include your `Image.open` if that helps – cbr Jan 06 '20 at 22:33
  • Ok so it does'nt display the image too. When I look to my DOM, I see that the image has a `src` attribute like that `src="data:image/jpg;base64,YidceGZmXHhkOFx4ZmZ..."` – johannchopin Jan 06 '20 at 22:59
  • 1
    That contains `\xff\xd8\xff` which is the start of JPG's header so appears alright. How large is your image? Data URLs do have [browser specific size limits](https://stackoverflow.com/questions/695151/data-protocol-url-size-limitations). If you don't specifically need to transfer that image over a websocket, you could add an endpoint in your server that generates whatever image you need to generate, and set the URL of that endpoint as the `src`. – cbr Jan 06 '20 at 23:09
  • 1
    It's a really little picture like `30x20` px so I don't think that is the problem. Moreover `format='JPG'` don't seems to be valid (I got an error) and after research I have seen that `JPG` is not the right format but `JPEG` is. – johannchopin Jan 06 '20 at 23:49