How to interpret a binary Bitmap picture, so I know which color on which pixel i change when changing something in the Code? - image

I just used this code to convert a picture to binary:
import io
tme = input("Name: ")
with io.open(tme, "rb") as se:
print(se.read())
se.close()
Now it looks like this:
5MEMMMMMMMMMMMMM777777777777777777777777777777777\x95\x95\x95\x95\x95\x95\x95\x95\x95\x95\x95\x95\x95MEEMMMMEEMM\x96\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97
And now I want to be able to interpret what this binary code is telling me exactly... I know it ruffly but not enough to be able to do anything on purpose. I searched the web but I didn't find anything that could help me on that point. Can you tell me how is it working or send me a link where I can read how it's done?

You can't just change random bytes in an image. There's a header at the start with the height and width, probably the date and a palette and information about the number of channels and bits per pixel. Then there is the image data which is often padded, and/or compressed.
So you need an imaging library like PIL/Pillow and code something like this:
from PIL import Image
im = Image.open('image.bmp').convert('RGB')
px = im.load()
# Look at pixel[4,4]
print (px[4,4])
# Make it red
px[4,4] = (255,0,0)
# Save to disk
im.save('result.bmp')
Documentation and examples available here.

The output should be printed in hexadecimal format. The first bytes in bitmap file are 'B' and 'M'.
You are attempting to print the content in ASCII. Moreover, it doesn't show the first bytes because the content has scrolled further down. Add print("start\n") to make sure you see the start of the output.
import io
import binascii
tme = 'path.bmp'
print("start") # make sure this line appears in console output
with io.open(tme, "rb") as se:
content = se.read()
print(binascii.hexlify(content))
Now you should see something like
start
b'424d26040100000000003...
42 is hex value for B
4d is hex value for M ...
The first 14 bytes in the file are BITMAPFILEHEADER
The next 40 bytes are BITMAPINFOHEADER
The bytes after that are color table (if any) and finally the actual pixels.
See BITMAPFILEHEADER and BITMAPINFOHEADER

Related

Hidden message in a picture

I'd like to read a hidden message in the following picture:
The message is supposed to look like CTF{Something}.
I've tried to find out how to read it for hours without success.
So far, I've tried to read the RGB values of each cell.
For instance, first cell (1, 1) is rgb(88, 101, 114) or #586572.
First three cells would give: Xer, ddnc which obviously makes non sense.
Last cell #587c00 rgb(88, 124, 0) is then supposed to be a }.
The only clue I have to solve that is RGB is a kind of ASCII.
Could you help me to solve that ?
This is an absolute spoiler for the puzzle, but here goes. I did truncate the actual flag out of the message, though, so you'll have some work to do.
With the original image 6x7 image in hand (the 192x224 image in the original post can be losslessly downscaled down to that), convert it to an uncompressed format such as Netpbm PPM, then simply look at the raw data (as the clue says).
$ convert 9TwkJ-6x7.png 9t.ppm
$ cat 9t.ppm
P6
6 7
255
Yes, decoding the colors as ASCII characters was the solution. [...]
You can get to the same result with e.g. Python with
>>> from PIL import Image
>>> im = Image.open("9TwkJ-6x7.png")
>>> im.tobytes()
b'Yes, decoding the colors as ASCII characters was the solution. [...]
A more devilish CTF would have e.g. rotated the source 90 degrees...
As for
For instance, first cell (1, 1) is rgb(88, 101, 114) or #586572. First three cells would give: Xer, ddnc which obviously makes non sense.
that smells like a different color profile wreaking havoc on your data; Yes, deco and Xer, ddnc are all just 1 RGB value here or there...

How I can load a font file with PIL.ImageFont.truetype in replit

I'm trying to make this welcome card thingy in discord.py and I'm running my bot on replit.com as of now.
font = ImageFont.truetype("arial.ttf", 28)
I got some examples and it worked great as long as I'm running it on my PC but wen I get to replit.com it gives the error saying
Command raised an exception: OSError: cannot open resource
How should I go about correcting this?
I don't know discord or replit but presume the issue is that you can't upload your binary font file.
If so, you have a couple of options:
find your desired font online somewhere and use requests.get(URL) to grab it in your code on replit, or
make a base64 variable in your code and decode it
The first option is covered here.
Let's look at the second. Say your font is called /Fonts/funky.ttf on your PC. Now you want that in base64 which you can do with a commandline tool on your local PC:
base64 < /Fonts/funky.txt
That will make a long string of characters. Copy it, and in your Python code add a string called font64 and set it equal to the pasted string, i.e.
font64 = 'PASTED STRING'
Now in your code you can convert the string back from base64 to binary, then wrap it in a BytesIO to make it look like a file and load it:
import base64
import io
from PIL import ImageFont
font64 = 'PASTED STRING'
# decode from base64 to binary
binary = base64.b64decode(font64)
# wrap in BytesIO to make file-like object
FileLike = io.BytesIO(binary)
# load font
font = ImageFont.truetype(FileLike, 28)

Other options to resize barcode for zebra printer using ZPL?

I want to print a Code 128 barcode with a Zebra printer. But I just can't get exactly where I want because the barcode is either too small or too big for the label size of 40x20 mm. Is there anything else I can try besides using the ^BY (Bar Code Field Default) module width and ratio?
^XA^PQ2^LH0,0^FS
^MUM
^GB40,20,0.1,B^FS
^FO1.5,4
^BY0.2
^BCN,10,N,N
^FD*030493LEJCG002999*^FS
^FO8,15
^A0N,3,3
^FD*030493LEJCG002830*^FS
^MUD
^XZ
Above script gives me a label that looks like this:
But when I just decrease the module width to 0.1 (which is the lowest) the barcode becomes too small and may be problematic to scan with a hand scanner:
Code-128 is a fixed-ratio code, so you would appear to have the choice of two sizes. You may be able to solve the problem by using a 300dpi printer in place of a 200.
If you can change the format (and I'm intrigued by the barcode and readable being different values) then you could save a little by printing one number-sequence and one alpha-sequence, as an even count of numerics will be encoded as alphabet C so you'd save one change-alphabet element.
Do you really need the * on each end?
Otherwise, perhaps code 39 (which prints the * if you use the print-interpretation-line option) would suit your purposes better.
Another Possibility is to do on the fly code-set changes, Try something like
^XA^PQ2^LH0,0^FS
^MUM
^GB60,20,0.1,B^FS
^FO1.5,4
^BY0.2
^BCN,10,N,N
^FD>:*>5030493>6LEJCG>5002830>6*^FS
^FO8,15
^A0N,3,3
^FD*030493LEJCG002830*^FS
^MUD
^XZ
This will allow less symbols to encode your data
If you can structure content to have all the alpha chars a one end or the other.
or (Depending on your firmware) you could use auto ^BCN,10,N,N,N,A

LibTIFF - Read 16bit image into array?

On the LibTIFF documentation, there is no mention or sample of how to read a 16 bit RGB image. Apparently also, using the scanline functions is required for reading a 16 bit. After a few attempts I couldn't get that to work.
According to this post,
If you want to handle all kind of TIFF image wihout using
TIFFReadRGBAImage then you have to detect the image format and use
low-level interface such as TIFFReadEncodedStrip and
TIFFReadEncodedTile
My end goal is to be able to get 16 bit values for the R,G and B channels, as well as actually know where they are in the image.
In the docs for libtiff they provide this sample code for eading using the strip encoding, however, they don't explain what is in the buf you get or how to make use of it. Can anyone explain how I am supposed to read the 16 bit values from that? Also, is there a way to consistent determine the strip order so I my read image is rendered correct?
TIFF* tif = TIFFOpen("myfile.tif", "r");
if (tif) {
tdata_t buf;
tstrip_t strip;
buf = _TIFFmalloc(TIFFStripSize(tif));
for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++)
TIFFReadEncodedStrip(tif, strip, buf, (tsize_t) -1);
_TIFFfree(buf);
TIFFClose(tif);
}

Image Copy Issue with Ruby File method each_byte

This problem has bugged me for a while.
I have a jpeg file that is 34.6 kilobytes. Let's call it Image A. Using Ruby, when I copy each line of Image A to a newly created file, called Image B, it is copied exactly. It is exactly the same size as Image A and is accessible.
Here is the code I used:
image_a = File.open('image_a.jpg', 'r')
image_b = File.open('image_b.jpg', 'w+')
image_a.each_line do |l|
image_b.write(l)
end
image_a.close
image_b.close
This code generates a perfect copy of image_a into image_b.
When I try to copy Image A into Image B, byte by byte, it copies successfully but the file size is 88.9 kilobytes rather than the 34.6 kilobytes. I can't access Image B. My mac system alerted me it may be damaged or is using a file format that isn't recognized.
The related code:
//same as before
image_a.each_byte do |b|
image_b.write(b)
end
//same as before
Why is Image B, when copied into byte by byte, larger than Image A? Why is it also damaged in some way, shape, or form? Why is Image A the same size as B, when copied line by line, and accessible?
My guess is the problem is an encoding issue. If so, Why does encoding format matter when copying byte by byte if they translate into the correct code points? Are code points jumbled up into each other so the parser is unable to differentiate between them?
Do \s and \n matter? It seems like it. I did some more research and I found that Image A had 128 lines of code whereas Image B had only one line.
Thanks for reading!
IO#each_byte iterates over bytes (aka Integers). IO#write, however, takes a string as an argument. So it converts the integer to a string via to_s.
Given the first byte in your image is 2551, you'd write the string "255" into image_b. This is why your image_b gets larger. You write number-strings into it.
Try the following when writing back bytes:
image_a.each_byte do |l|
image_b.write l.chr
end
1 As #stefan pointed out jpeg images start with FF D8. So the first byte is 255.

Resources