how to convert a png image to 1.0 binary without PIL / numpy Python

enter a description of the image here

Hello everyone.

The ultimate goal is to project the image onto a monochrome / LED screen We have a small image, black and white, initially in png format. dimensions in the region of 100x100px or even less. (Example at the very beginning)

We have Paint.net which allows you to convert to bmp, jpeg, tiff, tga and something else, if you need to specify. We also have a GIMP that turns us png into pbm.

Question. how easy and fast turn the image into a (punch card) plate of zeros and ones. It seems like the pbm already consists of zeros and ones. But I only managed to read it as a sequence of bytes. And yes, the plan is to then run all this on the microcontroller. So you need to make everything a minimum of the basic functionality

Author: Dmitrii_Argon, 2020-07-08

2 answers

You need to reduce the number of colors to two-then one pixel will take up one bit. But the picture should also be readable.

Taking the Gimp and the image

enter a description of the image here

Brightness-contrast, cropping, scaling, and discoloration up to bw and at the end of "image-mode-indexed" and you get this picture for a single-bit LCD display. (256*256 enlarged)

enter a description of the image here

Not a very convenient image for 100*100, but still recognizable

enter a description of the image here

Click export - and select the format "header file h"

/*  GIMP header image file format (INDEXED): /home/eri/Pictures/1567355672115958410.h  */

static unsigned int width = 256;
static unsigned int height = 256;



static unsigned char header_data_cmap[256][3] = {
    {  0,  0,  0},
    {255,255,255},
    {255,255,255},
    {255,255,255},

....

};
static unsigned char header_data[] = {
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
    0,1,0,1,0,0,1,0,0,1,0,1,0,1,0,1,
    0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,
    0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
    0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,

...

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};

header_data_cmap you can delete it-this is for color images, and header_data you cycle through and send it straight to the screen.

Packing in unsigned char is eight times more than you need, but there is no logic in the program on the controller. In the PBM (text) format, the sequence will be the text 0101010...

If saved in PBM (raw, binary) , then you read by byte and by an additional cycle with a shift get ones and zeros.

for b in data:
    for i in xrange(8):
        yield (b >> i) & 1
 7
Author: eri, 2020-07-09 00:05:52

Try it this way:


with open(path, mode="rb") as pbmfl:
    br = pbmfl.read()

def alignment(bin_num, target_len):
    cur_len = len(bin_num)
    if cur_len < target_len:
        return f'{"0"*(target_len-cur_len)}{bin_num}'
    else:
        return bin_num


bin_data = [alignment(f'{bs:b}', 8) for bs in list(br)])
print(''.join(bin_data))

Here, the function alignment aligns the resulting binary numbers to the specified length

 5
Author: cauf, 2020-07-08 17:28:43