Snippet - Convert Images to Display_N18.TinyBitmap format

I just posted Convert Images to Display_N18.TinyBitmap format on Codeshare. Feel free to discuss and make suggestions here.

2 Likes

We have been “secretly” working on n18 and graphics on memory-limited Cerberus and we maybe able to just use native bitmap just fine. There may not be need for tiny bitmap in future. We will know by next release.

Still, tiny bitmap will always be the most efficient way.

This is just a FYI and thanks for the contribution.

@ Gus - That is great news, if there is a way to use full bitmaps efficiently that would make life much easier.

I can’t wait to see/hear the details on what you have done. Have you dropped the color resolution? Personally I think that is a reasonable sacrifice on the low-end devices, I even have a 16 color bitmap that I can used to create full screen double buffers which will make game writing on these devices much more efficient, so if you have that solved I definitely want to wait for a more robust solution from you guys before moving further with my efforts.

@ taylorza - In the usage code, you have var myImageBytes line that I don’t believe is needed. Here is my edited version:


// Load the raw TinyBitmap bytes from the resources or any other storage medium
            //var myImageBytes = Resources.GetBytes(Resources.BinaryResources.MainMenu);
            // Create a tiny bitmap from the raw bytes. 
            // Note: You need to know the image dimensions is this is not encoded in
            // the raw image data.
            var tinybmp = new Display_N18.TinyBitmap(Resources.GetBytes(Resources.BinaryResources.MainMenu), 80, 80);  //myImagesBytes

            // Render the image to the display
            display_N18.Draw(tinybmp, 0, 0);

This seems like it would save precious ram on a Cerb board. Is there a way to actually create the var tinybmp as a resource to further reduce ram need? My data logger project is running out of ram when using the N18 module because of the menus I’ve put in it.

@ logictechs - Sorry for the late reply, I am travelling so I only check in here every now and then.

What you are saving is the allocation of a local variable to store the reference to the array. The array of bytes is still loaded and has the exact same life-time as the original code.

For sake of writting clear code I would not be overly concerned about the transient local variable storing a reference. There is nothing wrong with the change you have made, but I would not consider that a significant memory savings. At a guess you are saving at most 16 bytes, I will check once I am back home in a week or so.

I would put this down to more of a style question and in specific scenariois a performance optimization if this was in a loop, but that is a completely different discussion.

In the usage code you include the line

var tinybmp = new Display_N18.TinyBitmap(myImageBytes, 80, 80);

I cannot find the class Display_N18.TinyBitmap in the Display_N18 source <http://gadgeteer.codeplex.com/SourceControl/latest#Main/Modules/GHIElectronics/Display N18/Software/Display N18/Display_N18_42/Display_N18_42.cs>

Where would I pick it up?

By just adding the display n18 to your gadgeteer project…

It’s not a Gadgeteer project but a .NetMF one. I’m happy to pull in bits of the Gadgeteer code as required, but looking at the source for the N18 module I cannot see the Display_N18.TinyBitmap class.

On another thread https://www.ghielectronics.com/community/forum/topic?id=15362 taylorza has provided the explanation and a simple workaround:

[quote]
Sometime after that code was written GHI dropped the TinyBitmap from their interface and added support for handling standard .NETMF Bitmaps. However, using TinyBitmapConverter will still work for you.

To use DrawRaw, you should not be using the bytes you get from Bitmap.GetBitmap(), you need to have a raw byte buffer with just the pixel data, Bitmap.GetBitmap() includes bitmapinfoheader data etc.

Using TinyBitmapConverter you can convert a bmp to the raw byte 16bit representation and then add that file as a resource to your application. Once you have that, you can use the following code to render the bitmap.

var tdata = Resources.GetBytes(Resources.BinaryResources.yes_no);
 _display.DrawRaw(tdata, 13, 79, 50, 50);

Where Resources.BinaryResources.yes_no is the raw data and not the original bitmap.[/quote]

and here is a TinyBitmap Class in case you find it interesting:

https://mikroenetmf.codeplex.com/SourceControl/latest#DeviceCode/LEDONET/libraries/LEDONET.EasyDisplay/Managed/TinyBitmap.cs

Cheers,
Jay,

1 Like

Excellent, thanks Jay Jay. Very brief class and I can clearly see the two constructors and the issue taylorza mentioned whereby one takes a copy of the bytes, and one doesn’t:


public TinyBitmap(Bitmap bitmap)
{
    this.Width = (uint)bitmap.Width;
    this.Height = (uint)bitmap.Height;
    this.Data = new byte[this.Width * this.Height * 2];
    Util.BitmapConvertBPP(bitmap.GetBitmap(), this.Data, Util.BPP_Type.BPP16_BGR_BE);
}


public TinyBitmap(byte[] data, uint width, uint height)
{
    this.Width = width;
    this.Height = height;
    this.Data = data;
}