Python Forum

Full Version: Formatting outputs created with .join command
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I am doing a project on a Raspberry Pi Pico running Micro Python to which I am new at in terms of programming having never touch Python or any variant before I started a about a month ago.

I came here as I needed something to turn a small JPG image into a text file of RGB values my project and the only way I could find to do this was some code I found here. But this mostly dos what I want but not fully

The code I found here which was:

import cv2
img = cv2.imread('01.jpg')
with open('JpgtoRGBoutput.txt', 'w') as f_out: 
    for i in img: 
        f_out.write('|'.join(['{},{},{}'.format(*j) for j in i]) + '\n')
I've managed to adapt the code so it separates each pixel's RGB value onto a separate line by swapping the '|' part for '\n' so I get an output which reads something like:

162,53,2 231,127,80 211,116,72 157,56,11 190,67,11 191,57,0 198,61,0 195,68,0 166,58,4

but I now have 2 issues.

I need to add a number to identify the pixel before it's RGB value
I need each value to be 3 digits so instead of saying "255,25,5" I need it to say "001,255,025,005" (001 being the pixel number, the rest being the RGB value) because of how my micro python code reads the data into the Pico for use.
I tried this:

import cv2
img = cv2.imread('01.jpg')
cnt = 0
with open('JpgtoRGBoutput.txt', 'w') as f_out: 
    for i in img: 
        f_out.write('\n'+str(c)+",".join(['{},{},{}'.format(*j) for j in i]) + '\n')
        cnt += 1
But that only adds a number to the start of each line of pixels so I can work out that "i" is a line of pixels from the image and "j" presumably is a value within the line of pixels.

I've looked up the .join command but it confuses me because I am new to all of this. Can someone point me in the direction on how to achieve what I need to do?
It helps to break things up into smaller pieces.
import cv2


img = cv2.imread('test.jpg')
with open('JpgtoRGBoutput.txt', 'w') as f_out:
    offset = 0
    for row in img:
        pixels = [f'{index+offset:03},{r:03},{g:03},{b:03}' for index, (r, g, b) in enumerate(row)]
        print(','.join(pixels), file=f_out)
        offset += len(pixels)
In this code the join() and the pixel creation are split into separate statements. This might make it easer to see that the only thing join does is stitch together a sequence of strings.

To pad numbers to 3 digits with a leading zero, you add ":03" to the format. I used f'string formatting because I think it reads better than using format(). If you prefer using format.
pixels = ["{:03},{:03},{:03},{:03}".format(col+offset, *pixel) for col, pixel in enumerate(row)]
There is a problem with this code in that for any image larger than 1000 pixels, the index is larger than 3 digits. This is the last line for a 250x72 image.
Output:
17750,250,218,039,17751,245,209,0311...17998,152,118,065,17999,233,207,170
Just another way to pad with zeros - string method str.zfill(). It's actually more keystrokes than using f-string formatting but one can argue that more readable.


>>> for value in ("5", "25", "255", "2555"):
...     print(value.zfill(3))
...
005
025
255
2555