Society of Robots - Robot Forum

Software => Software => Topic started by: Commanderbob on July 11, 2008, 07:21:43 PM

Title: Image Compression
Post by: Commanderbob on July 11, 2008, 07:21:43 PM
I am using a 128*96 OLED in a project and I want to display a splash screen when it turns on. The problem is that an 8bit image will take up 12,288 bytes and a 16bit will take 24,576 bytes and I only have 256K of ROM (ATmega2561). The image is VERY simple with less then 10 colors. Any ideas on how to compress this image? A PNG of the image only takes 6,748 bytes and I think that is with 24 bit color.

Here are some ideas I had.
Since there are only 8 colors (if there are more I could make it 8) I could put two pixels into one byte.
I could have something like "blue for the next 50 pixels" instead of "blue,blue,blue,etc"
Well that is all I got right now...

The other major problem is how am I supposed to get this into C code? I could go through all 12,288 pixels and write a compressed file, but that would take forever and I have more then one picture I want to compress. Does anyone know if it is possible to convert a bitmap into a custom compressed C code? Maybe it could be possible to write a script to do it? I use Linux (Ubuntu 8.04).

If this is too complicated would it possible for the AVR to store/read PNG images? I have not been able to find any information of reading a PNG.

Thanks,
Justin
Title: Re: Image Compression
Post by: Commanderbob on July 11, 2008, 07:54:08 PM
Wow... I managed to get it down to 1014 bytes. The image is only 8 colors and saved as a PNG. How can I use this! Please if anyone knows a place I can find info on how PNG images are stored so I could read them that would be amazing.
Thanks,
Justin
Title: Re: Image Compression
Post by: izua on July 12, 2008, 05:32:28 AM
Here (http://en.wikipedia.org/wiki/Portable_Network_Graphics)'s a start.
Libraries for PNG operations in C/C++ are expensive by themselves in terms of cpu and memory. Anyway, what you should know is thast the image has to be recomposed from that data, meaning, you'll actually need 128 * 96 * 3 * color depth bits of RAM to display it (lcd needs refreshing)
Title: Re: Image Compression
Post by: Commanderbob on July 12, 2008, 09:00:14 AM
The OLED I am using has a built in controller and display RAM that I write to. Here is what I have come up with...
Use a pallet of 8 16bpp colors. The first half of each byte represents how many pixels are that color (in a row), while the second half shows the color. If there are more then 7 pixels in a row the first half would hold the value of 0 which would then tell the program to read the next byte. That way for pixels that have 1-7 colors in a row it only takes one byte to store them and for pixels 8-255 in a row it only takes two bytes. I think this way I could compress the image to a little over 1K. Now I just need a way to make Gimp save it as my custom format or write a program to convert an image to it.

Edit:I decided to do it by hand as it would take longer to write code to do it. I have not used struct objects very much before but how does this look?
Code: [Select]
typedef struct {
   static uint_8 width;
   static uint_8 hight;
   static uint_16 *color_map;
   static uint_8 *data_map;
}mf_img;

Would this allow me to do something like this?
Code: [Select]
mf_img splash;
splash.width=128;
splash.hight=96;
splash.color_map={1,2,3,4,5,6,7,8};
splash.data_map={0,129,15,23,0,45.............};

Also using static will make the data be stored in ROM right?

Thanks,
Justin