13

In C# I can declare new 48bitRGB or 64bitRGBA without problem, and in fact the right format is saved on disk.

However, when it comes to declaring a color, I am not able to declare color of more than 8-bit values. That seems to be because Color declarations expect no more than 8 bits per component.

The code I have so far:

int x;
int y;
int w = 512, h = 512;

Bitmap image = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format48bppRgb); //New image with 16bit per channel, no problem

// Double 'for' control structure to go pixel by pixel on the whole image
for (y = 0; y < h; y++)
{
    for (x = 0; x < w; x++)
    {
        comp = somevalue; //Numeric component value
        // Lo que vaya por aqui
        System.Drawing.Color newColor = System.Drawing.Color.FromArgb(255, comp, comp, comp); // <= Here is the problem, values can't exceed 256 levels
        image.SetPixel(x, y, newColor);
    }
}

image.Save(@"C:\test.png", System.Drawing.Imaging.ImageFormat.Png); //Saving image to disk

What is a method for declaring a 16-bit color component in C#?

gunr2171
  • 16,104
  • 25
  • 61
  • 88
  • 2
    you could access the raw pixels, see here how: http://stackoverflow.com/questions/7768711/setpixel-is-too-slow-is-there-a-faster-way-to-draw-to-bitmap – thumbmunkeys May 22 '15 at 09:51
  • 1
    System.Drawing.Color internally uses a long (signed 64 bit integer) to represent it's RGBA value but all of it's operations accept ints, you'll need to create your own Bitmap class or use an equivalent graphics format library. – Machinarius May 22 '15 at 09:58
  • Yes, I am using WPF, why? – Vicente Carratala May 22 '15 at 22:22

1 Answers1

3

The problem stems from the fact that the Bitmap class encapsulates a GDI+ bimap.

GDI+ version 1.0 and 1.1 can read 16-bits-per-channel images, but such images are converted to an 8-bits-per-channel format for processing, displaying, and saving. link

So when you are setting the value of the pixels you are dealing with the 8 bit per channel format.

If use use unsafe code you can access the values directly, see Get 64bpp image color.

Community
  • 1
  • 1
Stephen Turner
  • 7,125
  • 4
  • 51
  • 68
  • 1
    I was trying to avoid direct access, but it seems there is no better way. Thank you so much! – Vicente Carratala May 30 '15 at 14:20
  • You can avoid unsafe code by copying the entire backing array (or parts of it, depending on your operation) out of the image, and back in after processing, using `Marshal.Copy`. – Nyerguds Jan 09 '18 at 13:37