Tuesday, May 3, 2011

How apply Color Lut over bitmap image in c#

Hi,

I am opening different types of images like (8 and 16 bit) and they are (Monocrome, RGB ,palette color).

I have raw pixel data of these images. I create bitmap like this for 8 bit images.

          //for monocrome images i am passing PixelFormat.Format8bppIndexed.
          //for RGB images i am passing PixelFormat.Format24bppRgb
           PixelFormat format = PixelFormat.Format8bppIndexed;
           Bitmap bmp = new Bitmap(Img_Width, Img_Height,format);

           Rectangle rect = new Rectangle(0, 0, Img_Width, Img_Height);

           //locking the bitmap on memory
           BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, format);

           // copy the managed byte array to the bitmap's image data
           Marshal.Copy(rawPixel, 0, bmpData.Scan0, rawPixel.Length);
           bmp.UnlockBits(bmpData);


The problem is that when i draw that bmp image then it differs in color than original. So is there any way to apply lut (lookup table) on that colored images.

i want any unsafe code because i tried getixel and setPixel and they are very slow. I also dont want Image.fromSource() methods.

From stackoverflow
  • Take a look at the bitmap's Image.Palette property.

    prashant : I saw that but for RGB images Image.palette is 0. I am getting Image.Palette = 256 in case of monochrome and Palette color images. But for palette color images how can i get RGB byte array separately and how to apply on Image.Palette. I tried that but suppose Original image is in Green color. And i am getting image color violet from my code. So are it gives original green color if i will take separate RGB and apply on Image.palette. Thanks
    Alnitak : I don't know where you're getting your source data from, but you should be able to _write_ to the palette thus: bmp.Palette.Entries[0].r = red_value; etc. ImagePalette is a "ColorPalette" object, not just the number of entries.
    prashant : thanks, irst of ColorPalette is sealed class so you can't make palette from own.If image is not having. bmp.Palette is a property.But you can't set direct values on that. Because if bmp.Palette = 0 so their is no any entries. So if you trying bmp.Palette.Entries[i] give you out of bound exception. And if want to set bmp.Palette.Entries[i].R is a read only property.
  • As far as I know, .NET does not support ICC color profiles, so if you for instance open an image that is using the AdobeRGB color profile, the colours will appear a bit duller and more "greyish" than if you open the same image file in, say, Photoshop or another color-profile-aware software.

    This post discusses some color profile issues; you may find something of interest there.

    prashant : I am getting image.Palette = 256 for Palette color and monochrome images. But how can i reflect these palette to image. Because image looks incorrect.
  • GetPixel and SetPixel are indeed very slow. If you want to do operations on single pixels, consider using a FastBitmap. It allows to quickly color pixels. Using this unsafe bitmap will greatly improve your speed.

    prashant : this is something i want. Lets try..
  • Hi, i solved this problem see how. Somewhere i read that GDI+ return BGR value not the RGB. So i reverse the order and amazing everything fine. But it is little bit slow.

           PixelFormat format = PixelFormat.Format8bppIndexed;
           Bitmap bmp = new Bitmap(Img_Width, Img_Height,format);
    
           Rectangle rect = new Rectangle(0, 0, Img_Width, Img_Height);
    
           //locking the bitmap on memory
           BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, format);
           Marshal.Copy(rawPixel, 0, bmpData.Scan0, rawPixel.Length);
    
           int stride = bmpData.Stride;
           System.IntPtr Scan0 = bmpData.Scan0;
    
           unsafe
           {
               byte* p = (byte*)(void*)Scan0;
               int nOffset = stride - bmp.Width * SAMPLES_PER_PIXEL ;
               byte red, green, blue;
    
               for (int y = 0; y < bmp.Height; ++y)
                {
                    for (int x = 0; x < bmp.Width; ++x)
                    {
                        blue = p[0];
                        green = p[1];
                        red = p[2];
                        p[0] = red;
                        p[1] = green;
                        p[2] = blue;
                        p += 3;
                    }
                    p += nOffset;
                }
            }
    
            ////unlockimg the bitmap
            bmp.UnlockBits(bmpData);
    

    thanks

    Can anybody is having some faster code than that.

    prashant : Hi, Also its only working for RGB images. Because RGB images having all the three component (R,G,B). What about PaletteColor images. I am unable to understand the indexing of color in palette images. Are anybody handle Palette Color images.

0 comments:

Post a Comment