1

I'm working on a .Net app which uses lot of bitmaps.

If all my bitmaps are grayscale does it makes sens to have the Bitmap object set to 32bpp?

I'm asking because that's the default PixelFormat I use. I'm wondering if I convert the image to 16bpp or 8bpp it will reduce the size each bitmap object uses in memory?

Bottom line, does changing from PixelFormat.Format32bppRgb to PixelFormat.Format16bppGrayScale reduces the memory usage of each Bitmap instance by half?

Thanks,

iamkrillin
  • 6,798
  • 1
  • 24
  • 51
Matimont
  • 739
  • 3
  • 14
  • 33
  • 1
    Have you tried testing this yourself yet? – Mike Cheel Jun 20 '14 at 20:32
  • No, I don't know how to convert the images in the first place. So if the answer is yes, it will reduce the memory that it uses then I'll find out how to convert from 32 to 16 – Matimont Jun 20 '14 at 20:34

2 Answers2

3

The memory required to store a bitmap is, largely, proportional to the size of the pixel storage format. So an 8 bit grayscale bitmap will be a quarter of the size of a 32 bit RGBA bitmap.

I say largely because there is overhead associated with a bitmap. And there is padding due to scanline alignment requirements. But so long as the image data, the pixels, are sufficiently large, they will dominate. So the simple rule of thumb above is accurate.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Thanks, so how can I convert a 32bpp Bitmap to 8bpp or 16bpp? – Matimont Jun 20 '14 at 20:36
  • See here: http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.setresolution(v=vs.110).aspx Bitmap.SetResolution() – Mike Cheel Jun 20 '14 at 20:36
  • Kind of depends. On where the data comes from. I think I'd store it as `Format8bppIndexed` with a gray scale color table. But how you get there really depends on information we don't have. – David Heffernan Jun 20 '14 at 20:42
1

Bitmaps are complex. The answer of David is only partially correct. Bitmaps occupy three times the memory they need due to triple buffering used by GDI. This is an implementation detail which can change by e.g. using a different Bitmap ctor which calls a different ctor in GDI.

Windows 7 up to Windows 8.1 had a bug until April of this year that Bitmaps did occupy 3*64KB = 192KB address space regardless how small your bitmap is. I did report this bug to MS and this was the first time MS changed not my mind by telling me not to do that but they fixed the issue in Windows. See http://geekswithblogs.net/akraus1/archive/2014/01/03/155056.aspx. Yes grayscale will reduce the memory footprint but depending on the patch level of your OS you will still run quickly out of address space under 32 bit. The best thing is to keep the bitmaps on disc and load them only if you really need them. A compressed 32bpp rgb bitmap of 400byte size (e.g. a 48x48 icon) will inflate to around 3*6 KB in memory which is a lot bigger than the original icon.

Under the hood GDI bitmaps now use WIC (Windows Imaging Component) which may be patched in the future again for the better or worse.

Alois Kraus
  • 13,229
  • 1
  • 38
  • 64
  • I'm not familiar with any of these issues. Triple buffering? Why is that done? If what you say is true then I guess `byte[,]` is the way forward. – David Heffernan Jun 20 '14 at 21:06
  • GDI is full of wonders. Last time I have checked it with heap allocation profiling and xperf. It was not nice what I have seen. – Alois Kraus Jun 20 '14 at 21:12