How do I assign a buffer containing a Mono8 bitmap to a TBitmap?

How do I assign a buffer containing a Mono8 bitmap to a TBitmap?
(Link contains a lot more info and source code)
https://stackoverflow.com/q/51067460/49925?sgp=2

Comments

  1. I last did something with grayscale bitmaps in the Windows 3.1 days (when I was very excited to get my first graphics card capable of 256 colours!) I added a comment with some ideas, but by no means expert here.

    ReplyDelete
  2. Either use an RGB pixel format, converting from the mono8 value to RGB. Or use an 8 bit pixel format with a palette that you provide.

    ReplyDelete
  3. Thomas Mueller you have to set the pixelformat to pf8bit and the bitmap palette.
    Write into the bitmap through scanline is the right way.
    If you want to introduce an optimization get scanline pointer only 1 time before the "for" cycles. if you do that, pay attention at the image rowpitch witch usually multiple of 8 and DIB format, so bmp.scanline[bmp.height -1].
    Finally, if you have to run faster use the Intel IPP library!!!
    Let me know if you need some examples I can provide you tomorrow.

    ReplyDelete
  4. Davide Visconti an example would be really helpful.

    ReplyDelete
  5. Thomas Mueller - -I am thinking you want a 8 bit image (256 colors) with a palette that is grayscale (many shades of grey).

    A monochrome bitmap has two colours (not necessary black and white - any two colors), referencing a palette with two entries.

    I find it easiest to do this with a device independent bitmap, filling out a bitmap file header, a bitmap info (with the palette entries), and then bits. Use a TMemoryStream, then call Delphi's TBitmap.LoadFromStream() method.

    One thing: Each scanline must be DWORD aligned, so if you have 31 pixels, you still need to allocate need 32 bytes per scaline line row (for a eight bits per pixel image).

    Each vlalid pixel (byte) in the scanline will reference the index of the actual color in the palette.

    Professional hint from TJoe(h^): The Windows GDI (or drivers) may sometimes have trouble with the memory allocated in some versions of Delphi. I use always use a function like GlobalAlloc() foir the memory alloc to always ensure success (or use FastMM).

    You can also transfer the bitmap using several different ways with a device dependent bitmap and a Windows palette. I find that a bit more than goofy (and it is not cross performable), and it is also probably more work that it is worth.

    Eight bit grayscale images are a lot of fun, as the eye does not generally perceive the shades of gray generally mapped, leaving room for enhancements in the value used. The format is also fairly easy to write code for.

    As for code, I posted quite a few DIB snippets over the years, and perhaps even TI or two on the subject. I would think It should be petty easy to find (?).

    Hope that helps!

    Joe

    ReplyDelete
  6. I solved the problem. Actually there were two:
    1. Some other code which is called with that bitmap changed the format to 24 bits, which explains the 1/4 size.
    2. I had to assign a grayscale palette to get the right colours.

    ReplyDelete
  7. Hi Thomas Mueller, I hope it will be usefull for you.
    ;-)
    Different ways, different speed.

    drive.google.com - Demo_CopyImage.zip

    ReplyDelete
  8. Davide Visconti thanks. That was indeed useful.

    ReplyDelete

Post a Comment