I need to convert an image to binary. The result should be a 256 indexed binary file with the color format RGB565 16bit(1 color 2 bytes)
This format is used to store image background for watchfaces on cheap smartwaches.
https://github.com/fbiego/dt78/blob/master/firmware/watchface.md#decoded
https://lvgl.io/tools/imageconverter
This tool can create and indexed binary files but the format is RGBA 32bit (4 bytes per color) and also pads extra bytes at the start of the file.
What algorithm is used to create an indexed binary from an image?
Are there any Kotlin frameworks that can do this?
Related
The tests I made were not conclusive.
There are imagens with 3MB, but with small dimensions that generate small strings.
There are images with few Ks, but with large dimensions that generate large strings.
What is the weight of each of these characteristics?
And does the image format count?
There is a direct relationship between:
the size of a JPEG-encoded image and its base64 representation,
between a TIFF-encoded image and its base64 representation,
between a PNG-encoded image and its base64 representation.
That relationship is that the base64 version will be around 33% bigger.
However, there is no relationship between an image and its base64 representation if the file format is not specified. The reason is that the file format (and image content) are likely to grossly affect the compression achieved - if indeed the format supports compression.
For example, the same simple red rectangle of size 1024x768 pixels could take:
5MB to encode as an uncompressed TIFF, or
5kB as an LZW compressed TIF, or
9kB as a JPEG, or
2.5MB as a BMP
all we can say is that the base64 versions will be around 33% bigger.
Note further, that it is not even sufficient to stipulate that you want to predict the size of the base64 representation when, say, JPEG encoded - because the size will still depend on the quality setting used for the JPEG encoding... likewise the compression method and bit-depth used in a TIFF encoder.
After I read in https://en.wikipedia.org/wiki/Base64 about how the word Man gets converted into TWFu by using the base64 algorithm, I was wondering how an image get converted by the same algorithm, after all this conversion takes bytes ,divide them into groups of 6 and then looking for their ASCII value.
My question is, how an image becomes a base64-encoded string?
I want an answer that describes the flow from when we save the image in our computer until it becomes a base64-string.
Terms that I hope will be explained in the answer are:
pixels/dpi/ppi/1bit/8bit/24bit/Mime.
Base64 isn't an image encoder, it's a byte encoder, important distinction. Whatever you pass it, whether it be a picture, an mp3, or the string "ilikepie" - it takes those bytes and generates a text representation of them. It has no understanding of anything in your pixels/dpi/ppi/1bit/8bit/24bit/Mime list, that would be the business of the software that reads those original bytes.
Per request I want an answer that describes the flow from when we save the image in our computer until it's become 64base string.
To get to a base64 representation:
Open paint and draw a smiley face.
Save that smiley face as smile.png
Paint uses its png encoder to convert the bitmap of pixels into a stream of bytes that it compresses and appends headers to so that when it sees those bytes again it knows how to display them.
Image is written to disk as series of bytes.
You run a base64 encoder on smile.png.
base64 reads the bytes from disk at the location smile.png refers to and converts their representation and displays the result.
To display that base64 representation in a browser:
browser is handed a resource encoded with base64, which looks something data:image/png;base64,blahblah...
Browser takes the image/png part and knows that the data following it will be the bytes of a png image.
It then sees base64, and knows that the next blob will need to be base64 decoded, before it can then be decoded by its png decoder.
It converts the base64 string to bytes.
It passes those bytes to its png decoder.
It gets a bitmap graphic that it can then display.
every image is consists of many pixels, the number of pixel is determined by the image resolution.
image resolution - the number of pixels in a row & number of rows.
for example image with resolution of 800x600 has 800 pixels in a row & 600 rows.
every pixel has bit depth - the number of bits represent pixel.
for example with bit depth of 1 every pixel is represent by one bit and has only 2 options (0 or 1 - black or white).
image can saved in many different formats. the most common are bitmap , jpeg, gif. whatever format is used an image always displayed in computer screens as bitmap (uncompressed format). every format is saved differently.
jpeg- is a 24 bit (bit depth) format. when you stored the image it work in compressed form and you loss some of the image data.
gif- up to 8 bit (bit depth) format. a gif image can be optimized by removing some of the colours in its palette. it is a lossless format.
Just throwing this in for the Bytes clarification :
"The word MAN gets converted into TWFu by using the base64 algorithm, I was wondering how an image gets converted by the same
algorithm, after all this conversion takes Bytes, divide them into
groups of 6 and then looking for their ASCII value."
"My question is, How an image becomes base64 string?"
correction : MAN becomes TUFO. It is actually Man that becomes TWFu as you've shown above.
Now onto the clarification...
The byte values (binary numbers) of the image can be represented in hex notation, which makes it possible to process those same bytes as a string. Hex has a range from 0 up to F which means.. ranging 0 to 9 then it's A = 10 up F = 15. Giving 16 possible values.
Hex is also called Base16.
Bytes conversion to Base64 is simply : Numbers converted from Base16 to Base64.
The Hex range of 0 to F is within Base64 valid chars and so can be written as Base64.
For example :
The beginning 3 bytes of JPEG format are always ff d8 ff
The same as Base64 is : /9j/ ...(see examples at these link1 and link2)
You can test by :
Open any .jpg image in a downloaded free Hex Editor. You can also try online Hex editors but most won't Copy to clipboard. This online HEX viewer will allow Select/Copy but you have to manually remove all those extra minus - in copied hex text (ie: use the Find & Replace option in some text editor), or skip/avoid selecting them before any copy/paste.
Go to this Data Converter and re-type or copy/paste as many bytes (from starting FF up to any X amount) into the [HEX] box and press decode below it. This will show you those bytes as Base64 and even tells you the decimal value of each byte.
When you upload any file in a html form using <input type="file>" it is transferred to server in the exactly same form as it is stored on your computer or device. Browser doesn't check what file format is and traits it as just block of bytes. For transfer details see How does HTTP file upload work?
I'd like to know which is the image format which permits me to encode losslessly 0xFFFFFF colors, but I need the one which occupies less space on disk. I know that BMP, JPEG(variant), TIFF, PNG,(just to say some) are lossless, but which one is the one that, considering also zipping or whatever, can occupy less space?
A PNG image (16million.png) containing all possible RGB888 colors was published in 1996. It occupies 115,989 bytes. I have converted the same image to a MNG file of just 472 bytes. The current version of pngcrush (1.8.0) brings the PNG file down to 91514 bytes.
See Khalid Sayood's Lossless Compression Handbook.
If on the other hand you are asking about a format that can represent a single pixel in any one of the 16 million colors, then PNG takes 69 bytes
including the 8-byte PNG signature, the IHDR, IEND, and IDAT chunk overhead, and several bytes of zlib overhead within the IDAT chunk, while a simple PPM file only takes 14 bytes to represent such single-pixel images (P6 1 1 255 \n red green blue).
Between those extremes, the best compression depends upon the content of the image.
The following is from TIFF 6.0 Specification Section 9: PackBits Compression
That is the essence of the algorithm. Here are some additional rules:
Pack each row separately. Do not compress across row boundaries.
The number of uncompressed bytes per row is defined to be (ImageWidth + 7)
/ 8. If the uncompressed bitmap is required to have an even number of bytes per
row, decompress into word-aligned buffers.
If a run is larger than 128 bytes, encode the remainder of the run as one or more
additional replicate runs
The first and the third items are easy to understand but I am confused about the second one specifically this: The number of uncompressed bytes per row is defined to be (ImageWidth + 7) / 8. Isn't that only true for 1 bit bi-level image. But to my knowledge, packbits is a byte oriented compression algorithm, it could be used for any type of tiff.
Could someone who knows about tiff and packbits give me some hints?
The TIFF document from this site: http://www.fileformat.info/format/tiff/corion-packbits.htm
has the following at the top:
Abstract
This document describes a simple compression scheme for bilevel
scanned and paint type files.
Motivation
The TIFF specification defines a number of compression schemes.
Compression type 1 is really no compression, other than basic
pixel packing. Compression type 2, based on CCITT 1D
compression, is powerful, but not trivial to implement.
Compression type 5 is typically very effective for most bilevel
images, as well as many deeper images such as palette color and
grayscale images, but is also not trivial to implement. PackBits
is a simple but often effective alternative
So it is clear the additional rules are with respect to bilevel images. For some reason, the above abstract and description are missing from the pdf version of TIFF6.0.
I'm building one part of H264 encoder. For testing system, I need to created input image for encoding. We have a programme for read image to RAM file format to use.
My question is how to create a RAW file: bitmap or tiff (I don't want to use compressed format link JPEG)? I googled and recognize alot of raw file type. So what type i should use and how to create? . I think i will use C/C++ or Matlab to create raw file.
P/S: my need format is : YUV ( or Y Cb Cr) 4:2:0 and 8 bit colour deepth
The easiest raw format is just a stream of numbers, representing the pixels. Each raw format can be associated with metadata such as:
width, heigth
width / image row (ie. gstreamer & x-window align each row to dword boundaries)
bits per pixel
byte format / endianness (if 16 bits per pixel or more)
number of image channels
color system HSV, RGB, Bayer, YUV
order of channels, e.g. RGBA, ABGR, GBR
planar vs. packed (or FOURCC code)
or this metadata can be just an internal specification...
I believe one of the easiest approaches (after of course a steep learning curve :) is to use e.g. gstreamer, where you can use existing file/stream sources that read data from camera, file, pre-existing jpeg etc. and pass those raw streams inside a defined pipeline. One useful element is a filesink, which would simply write a single or few successive raw data frames to your filesystem. The gstreamer infrastructure has possibly hundreds of converters and filters, btw. including h264 encoder...
I would bet that if you just dump your memory, that output will conform already to some FOURCC -format (also recognized by gstreamer).