converting png file to bytearray

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
User avatar
devnull
Posts: 221
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

converting png file to bytearray

Post by devnull » Thu May 17, 2018 2:20 am

I am trying to convert .png icons to bytearrays to use in displays.

Image
Image
Image
Image

Code: Select all

def png2ba(file='img.png',name='icon'):
  with open(file, "rb") as imageFile:
    src = imageFile.read()
  
  tgt = open(name+'py', 'wb')
  tgt.write(bytearray(src,"utf-8"))
  tgt.close()
But I cannot get past this error:

Code: Select all

UnicodeDecodeError: 'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)
This is the src:

Code: Select all

'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00(\x00\x00\x00(\x08\x03\x00\x00\x00\xbb H_\x00\x00\x01MPLTE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1\x8e%!\x00\x00\x00ntRNS\x00\x01\x02\x04\x05\x06\x08\t\n\x0f\x10\x11\x12\x13\x14\x15\x17\x18\x1a\x1c\x1e "$&\')*2348=>?@CDEKMNPRVXY[\\]abdfghikmoqstuwxy~\x82\x83\x86\x89\x91\x94\x97\x98\xa2\xa3\xa5\xaa\xab\xad\xaf\xba\xbe\xc7\xca\xcc\xce\xcf\xd1\xd5\xd7\xd9\xda\xdc\xe2\xe4\xe6\xe8\xe9\xeb\xed\xf1\xf3\xf5\xf7\xf9\xfb\xfd\xf5\x04(\xa6\x00\x00\x01\x8dIDAT\x18\x19\xd5\xc1YC\x12Q\x00\x86\xe1\xefL\x14\xa0\x98\x96i\x9b\xed\xd9\x82\x95\x95&c\x9bE\xb6\xd0\x9e\xa5Q\x01\xb6Pj\xc0\xfb\xff/;\x87\xe1\xcc\xb0\xe5\xbd\xcf\xa3\xbd\'8q\xe7}e\xbb\xfe\xf9\xc5\xd51\xed"\xfd\xe8/\xb1\xca9\xa3\xe1\xcc\x02\xbd6\xa74Lf\x83\x01w5h\xec\x17\x91\xf5\xd5\xe5\x87/\x7f\x12ye\xd4\'S\xc7\xa9\x9d\xdd\xa7\xb6\xdc\x83\x16\xces\xf52\x1b87\x8cb\x995\x9c\xbcz,b\xedL\xab\xc7c\xacVV]28\xd3\xeaxS=#\xe7\x19\xd6[u)b\xcd\xcb\x83P\x8e\xf9\x8a5\xa1X\xd0\x00jF\x1e\x84j\x9b\xc2**v\x12\xeb\xbcb\x10*\xf2\t\xd82\xf2\x96\xb0R\x8aA\xa8\xc8E\xac\x11yk\xc0\xba\x12\x10*2\x8a5#\xaf\x06<U\x02BE\x02\xac\xcb\xf2v\x80e% T\x07\xd6My\x7f\x80\xfbr\xd2[\xb4\x85\xea\xc0\xba&\xaf\x0c\x94\xe4\x1c$RP$\x855+\xaf\x04\xfc\x90\x13\xdc\x0e\x9d\xc2\xb8"\x93XG\xe5\xe5\xb1F5\xc4\x12\xd6\x01y\xe3X\xf74(\xa8\x03e%6\x81fZ\x03\xf2Xy%f\xb1\xde\xa9_\xb6\t4RJ\x98\xefX+\xea\xb5\xbf\x8a\xb5\xa0n\xc7qV\x8d\xbad\xabX\xdf\x02\xf5(\xe2\x94\x8f\xc8\x0b\xe6\x9aX\xcd\t\xf5yM\xdb\xc7\x0b#\x81\x94\x9a,\xfc\xa6mF\xfdL\x89A\xadS\x1ab\x9e~\x95C\x1a*\xf7\x81n\x8d\xc5@\xffs\xf8\xc96\x1d_\xe6R\xda\x8d\xc9\x9d\xber\xeb\xfa\xa5ci\xedA\xff\x00&\x12\xb0(\xf9\xe7\x9f{\x00\x00\x00\x00IEND\xaeB`\x82'
I have tried setting encoding to 'uft-8' and 'ascii' and neither work, any suggestions on how to achieve this or does anyone know of a ready made script that I can use to save re-inventing the wheel ??

User avatar
dhylands
Posts: 2853
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: converting png file to bytearray

Post by dhylands » Thu May 17, 2018 5:25 am

So you're trying to write python source code which would create the same byte array as in the original png file?

User avatar
devnull
Posts: 221
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

Re: converting png file to bytearray

Post by devnull » Thu May 17, 2018 5:38 am

Yes,

This is a sample: https://github.com/mcauser/micropython- ... ge_dark.py

It is used to display an image on e-paper display as a buffer.

Code: Select all

# write hello world with black bg and white text
from image_dark import hello_world_dark
e.clear_frame_memory(b'\xFF')
e.set_frame_memory(hello_world_dark, x, y, w, h)
e.display_frame()
But I suspect that you can't just convert a file to bytearray as the example above only contains \XFF and \X00 so I am guessing that it would need to be converted pixel by pixel, no idea how I would do that !

OutoftheBOTS_
Posts: 394
Joined: Mon Nov 20, 2017 10:18 am

Re: converting png file to bytearray

Post by OutoftheBOTS_ » Thu May 17, 2018 5:39 am

I am a little new to programming but I though this line of code creates a bytearray called src??? src = imageFile.read()

User avatar
dhylands
Posts: 2853
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: converting png file to bytearray

Post by dhylands » Thu May 17, 2018 5:42 am

In which case, something like this should work:

Code: Select all

def png2ba(file='img.png',name='icon'):
  with open(file, "rb") as imageFile:
    src = imageFile.read()
  
  with open(name + '.py', 'wb') as tgt:
    tgt.write("x = ")
    tgt.write(repr(src))
    tgt.write('\n')

User avatar
devnull
Posts: 221
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

Re: converting png file to bytearray

Post by devnull » Thu May 17, 2018 5:45 am

OutoftheBOTS_ wrote:
Thu May 17, 2018 5:39 am
I am a little new to programming but I though this line of code creates a bytearray called src??? src = imageFile.read()
Thanks, I think you missed this later in the same post:

Code: Select all

UnicodeDecodeError: 'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)
Also, I now realise that simply converting it is not enough, as the desired bytearray(see link above) is effectively a pixel-on and pixel-off to be used in the framebuffer to recreate the image.

OutoftheBOTS_
Posts: 394
Joined: Mon Nov 20, 2017 10:18 am

Re: converting png file to bytearray

Post by OutoftheBOTS_ » Thu May 17, 2018 5:49 am

Again if I am wrong someone can correct me. Doesn't PNG files have a compression routine and also have 4 channels (R,G,B,opacity) not 3 (R,G,B).

I have been using BMP files to be able to load straight to a buffer to dump to memory of a display. The first 54 bytes are the header with info about the file then all the rest is the data in an uncompressed state. You can use many picture editing programs to create a 1 bit BMP file from most images (I use Photoshop myself).

User avatar
devnull
Posts: 221
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

Re: converting png file to bytearray

Post by devnull » Thu May 17, 2018 5:54 am

Thanks Dave, that indeed did not error and generated the file, however I now realise that the sample file looks completely different from the data that is generated by this conversion:

https://raw.githubusercontent.com/mcaus ... ge_dark.py

Code: Select all

bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x......
And this is what is generated by my conversion:

Code: Select all

'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00(\x00\x00\x00(\x08\x03\x00\x00\x00\xbb H_\x00\x00\x01MPLTE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1\x8e%!\x00\x00\x00ntRNS\x00\x01\x02\x04\x05\x06\x08\t\n\x0f\x10\x11\x12\x13\x14\x15\x17\x18\x1a\x1c\x1e "$&\')*2348=>?@CDEKMNPRVXY[\\]abdfghikmoqstuwxy~\x82\x83\x86\x89\x91\x94\x97\x98\xa2\xa3\xa5\xaa\xab\xad\xaf\xba\xbe\xc7\xca\xcc\xce\xcf\xd1\xd5\xd7\xd9\xda\xdc\xe2\xe4\xe6\xe8\xe9\xeb\xed\xf1\xf3\xf5\xf7\xf9\xfb\xfd\xf5\x04(\xa6\x00\x00\x01\x8dIDAT\x18\x19\xd5\xc1YC\x12Q\x00\x86\xe1\xefL\x14\xa0\x98\x96i\x9b\xed\xd9\x82\x95\x95&c\x9bE\xb6\xd0\x9e\xa5Q\x01\xb6Pj\xc0\xfb\xff/;\x87\xe1\xcc\xb0\xe5\xbd\xcf\xa3\xbd\'8q\xe7}e\xbb\xfe\xf9\xc5\xd51\xed"\xfd\xe8/\xb1\xca9\xa3\xe1\xcc\x02\xbd6\xa74Lf\x83\x01w5h\xec\x17\x91\xf5\xd5\xe5\x87/\x7f\x12ye\xd4\'S\xc7\xa9\x9d\xdd\xa7\xb6\xdc\x83\x16\xces\xf52\x1b87\x8cb\x995\x9c\xbcz,b\xedL\xab\xc7c\xacVV]28\xd3\xeaxS=#\xe7\x19\xd6[u)b\xcd\xcb\x83P\x8e\xf9\x8a5\xa1X\xd0\x00jF\x1e\x84j\x9b\xc2**v\x12\xeb\xbcb\x10*\xf2\t\xd82\xf2\x96\xb0R\x8aA\xa8\xc8E\xac\x11yk\xc0\xba\x12\x10*2\x8a5#\xaf\x06<U\x02BE\x02\xac\xcb\xf2v\x80e% T\x07\xd6My\x7f\x80\xfbr\xd2[\xb4\x85\xea\xc0\xba&\xaf\x0c\x94\xe4\x1c$RP$\x855+\xaf\x04\xfc\x90\x13\xdc\x0e\x9d\xc2\xb8"\x93XG\xe5\xe5\xb1F5\xc4\x12\xd6\x01y\xe3X\xf74(\xa8\x03e%6\x81fZ\x03\xf2Xy%f\xb1\xde\xa9_\xb6\t4RJ\x98\xefX+\xea\xb5\xbf\x8a\xb5\xa0n\xc7qV\x8d\xbad\xabX\xdf\x02\xf5(\xe2\x94\x8f\xc8\x0b\xe6\x9aX\xcd\t\xf5yM\xdb\xc7\x0b#\x81\x94\x9a,\xfc\xa6mF\xfdL\x89A\xadS\x1ab\x9e~\x95C\x1a*\xf7\x81n\x8d\xc5@\xffs\xf8\xc96\x1d_\xe6R\xda\x8d\xc9\x9d\xber\xeb\xfa\xa5ci\xedA\xff\x00&\x12\xb0(\xf9\xe7\x9f{\x00\x00\x00\x00IEND\xaeB`\x82'
So I suspect that the sample file is just pixels on and off, wheras the file I converted is not !

User avatar
devnull
Posts: 221
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

Re: converting png file to bytearray

Post by devnull » Thu May 17, 2018 5:55 am

Again if I am wrong someone can correct me. Doesn't PNG files have a compression routine and also
Thanks, yes you could be right, I don't know as I have never worked with image files before.

User avatar
dhylands
Posts: 2853
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: converting png file to bytearray

Post by dhylands » Thu May 17, 2018 6:12 am

Right. You don't want the raw PNG file, but rather what the PNG file would look like once it's decoded into memory.

PNG files can incorporate compression, and you may need to consider pixel conversion. i.e. if your source PNG was an 24-bit-per-pixel image and you wanted a 1-bit-per-pixel PNG file.

You'll probably want to use CPython and something like Pillow to read in an arbitrary image, decode it, rotate it, and colorspace convert it, then write out the python source.

Something like Image.convert can be used to convert to 1-bit black/white https://pillow.readthedocs.io/en/3.1.x/ ... ge.convert and Image.rotate to rotate by 90 or 270 as appropriate.

Post Reply