• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 699
  • Last Modified:

GDI+ and 48-bit images

I read in some Microsoft documentation that GDI+ only displays/handles 8-bit per channel (24bit max) images; 48-bit images aren't supported for "GDI+ version 1.0"  Is this still true?  Surely there will be 48-bit support somewhere down the road?  I'd love to start using GDI+ and dig into it with the .NET platform, but I need support for 48-bits.  Any comments or suggestions?

Thanks!

0
jimrwilson
Asked:
jimrwilson
  • 4
  • 3
  • 3
  • +1
1 Solution
 
AlexFMCommented:
GDI+ is high-level graphics library which uses standard GDI windows resources. Only 8 bpp images can be drawn in Windows, and I never heard that it will be changed.
If you want to show images with more than 8 bpp in the Windows platform, you need to convert them first loosing image resolution.
0
 
SalteCommented:
Here is how you can display 48 bit images in windows using GDI+:

1. Forget it.

2. If you still insist, keep only the high 8 bits of each color and treat the image as 24-bit for each pixel.

3. Wait until GDI implement some function to do (2) above. Don't hold your breath!

4. Switch to Linux and X-windows.

The point is that you might at some point in future find support for 48 bits per pixel in some window drawing package. However, the underlying window systems would still use maximum 8 bit per color per pixel and so you wouldn't be able to make use of the higher color resolution.

Now if you think that 16 bits per color is absolutely vital and that your images will look ghastly on a 24-bit color resolution then perhaps you really should reconsider your choice of windowing system. My bet is that it won't make much difference. Yes, 256 colors is bad, many people thought it was a major improvement over 16 colors as it used to be but still it wasn't good enough for most pictures. However, with 24 bit colors we really have at least the same color resolution as you will find in movies, I believe all DVD movies released these days uses 32 bit resolution which really is 24 bits but uses 8 bits for transparency which isn't used in a movie so the compressed format has actually far fewer.

Also for still pictures 32-bit or 24-bit is usually more than good enough for most ordinary work. Now, there may be special jobs that require more than this but MS doesn't sell to special markets, they sell to the mass market and in this mass market 24/32 bits is good enough for a long time to come and so they have no immediate plans to change their underlying window system to use 48 bits per pixel.

If you plan to show your image fast, as a movie or in a game - you definitely want to change the bits per pixel in the image long time before you save it on the CD and use it in your software. Converting on the fly is a bad idea.

If you plan to show your image as a still image in a one-time event you can always convert it on the fly by reading the image ignoring the lower 8 bits for each color and changing the image to a 24-bit per pixel or 32 bit per pixel .bmp file and then show that .bmp file under windows. If you plan to do it more than once I suggest you convert and then save the converted image as a .bmp and uses that as your input to your software.

The conversion is simple enough, you will use only the 8 more significant bits of each color:

if you have pixel info in an array of short like this:

short * p;

p[0] == red value, p[1] == green value, p[2] == blue, p[3] == red value of next pixel etc...
Then you build up a .bmp image (read the microsoft specification for the .bmp file format) using a byte array:

unsigned char * b;

The line length is a separate issue since the .bmp specification require that line length is always a multiple of 4, so if you use 24 bits per pixel you must multiply width by 3 and then add 0-3 bytes in order to make the result a multiple of 4.

Then store the pixel values in such a way that you store the red, green and blue values in the manner which .bmp file require.

One question is how to convert the 16 bit to 8. Taking the 8 more significant bits is perhaps not always what you want, perhaps you should use rounding:

if the lower 8 byte value is 128 or more you should add one to the high byte. However, in this case you should be aware that if the high byte is exactly the value 255 then you should not do any rounding. Due to this exception to 255 you actually then get a wrong distribution of the colors in which a value of 255 indicated a value in the range 65536-128..65535 a range of only 128 different 16-bit values, while the value 254 had a range of
65536-384..65536-129 or 256 different values.

The situation isn't perfect but who said that life was perfect? I therefore suggest rounding but with special test for the case 255.

unsigned char round(unsigned short v)
{
   unsigned char h = static_cast<unsigned char>(v >> 8);
   if (h < 255 && static_cast<signed char>(v) < 0)
      ++h;
   return h;
}

In this I made use of the fact that testing for >= 128 for an unsigned value is the same as testing for < 0 for a signed value and that < 0 is usually more efficient than testing for >= 128 :-)

Declaring that function to be inline and make a loop, probably with loop unrolling and repeatedly call this function as you copy the pixel colors from source image to the destination .bmp image should get you there.

Alf
0
 
udilCommented:
This question has been abandoned. I will make a recommendation to the moderators on its resolution in a week or two. I appreciate any comments that would help me to make a recommendation.

In the absence of responses, I may recommend DELETE unless it is clear to me that it has value as a PAQ. Silence = you don't care

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Udil
EE Cleanup Volunteer
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
SalteCommented:
I do think that my response is worth saving. I don't know why jimrwilson never bothered to respond.

Alf
0
 
udilCommented:
It's possible that my recommendation will be to accept your answer.
The guidance for my recommendation is in http://www.experts-exchange.com/help/cleanup.jsp.

Udil
EE Cleanup Volunteer
0
 
AlexFMCommented:
udil, I got a number of notifications from your cleanup work. In all of them you suggest to delete the question without accepting of the answers. Other EE moderators usually pick one of the answers to accept if there are no objections. In this particular case, I tnink, Salte deserves these points. There was a number of questions where I think points should be mine, but I don't want to fight for them in each question.
I hope it is not a new EE policy to deltete all questions without accepting the answers - this may be done programmatically. Please review your approach and try choose the best answer if it is possible. Thanks.
0
 
udilCommented:
AlexFM,

I'm sorry if I was misunderstood. The policy has not been changed, I just send a message prior to the ordinary recommendation message, in order to get help in making the recommendation. If there are places where you think the points should be yours, please don't hesitate to send a comment claiming that.

Udil
EE Cleanup Volunteer
0
 
AlexFMCommented:
I just want to say that if you see the best question, please suggest to accept it. At least, other EE moderators do this. According to your profile, you are good in C++, so I beleive it is not a problem for you. Thank you.
0
 
udilCommented:
>> see the best question

You mean: best answer. :)

>> please suggest to accept it

Will do.


Udil
EE Cleanup Volunteer
0
 
jimrwilsonAuthor Commented:
Thanks for the reply, Salte.
After further investigation, I see that you are right- GDI and GDI+ do not directly display 16-bit images.  DIB's must be shifted down to 8 bits per color (channel) before the GDI will display them.  We do work with the full 16-bits per channel of information, as this provides better accuracy after image manipulation (rotation, color and gamma correction, scaling, etc.)  We ended up doing a lot of our own routines, as well as a specialized library that is now a bit outdated.

Jim
0
 
SalteCommented:
PNG support 48 bit colors and if you display PNG on windows it will automatically have to scale down the color depth. If you want to keep 48 bit colors you can store your images as PNG on disk and then if and when you port to a windowing system or a future version of windows GDI support 48 bit images you already have them and don't need to do anything. All, you have to do is make sure you have a PNG loader for windows ;)

Alf
0

Featured Post

[Webinar] Improve your customer journey

A positive customer journey is important in attracting and retaining business. To improve this experience, you can use Google Maps APIs to increase checkout conversions, boost user engagement, and optimize order fulfillment. Learn how in this webinar presented by Dito.

  • 4
  • 3
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now