Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C#ImageProcessing
Hi!
I´m trying to edit 16 bit image data but I can´t access the full 16 bit of each pixel.
The following code is working flawlessly with 8 bit images.
 
private void ImageEditing()
{            
    //opening a 8 bit per pixel jpg image
    Bitmap bmp = new Bitmap("Image.jpg");
 
    int Width = bmp.Width;
    int Height = bmp.Height;
 
    //creating the bitmapdata and lock bits
    System.Drawing.Rectangle rec = new System.Drawing.Rectangle(0, 0, Width, Height);
    BitmapData bmd = bmp.LockBits(rec, ImageLockMode.ReadOnly, bmp.PixelFormat);
 
    unsafe
    {
        //iterating through all the pixels in y direction
        for (int y = 0; y < Height; y++)
        {
            //getting the pixels of current row
            byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride);
 
            //iterating through all the pixels in x direction
            for (int x = 0; x < Width; x++)
            {
                //getting index of current pixel (3 because of the 3 * 8bits per pixel)
                int index = x * 3;
 
                //getting R, G and B values
                byte R = row[index + 2];
                byte G = row[index + 1];
                byte B = row[index];
            }
        }
    }
 
    //unlocking bits and disposing image
    bmp.UnlockBits(bmd);
    bmp.Dispose();
}
 
If I want to adapt it to 16 bit and replace bytes with ushorts(unsigned 16 bit integer) and also open a 16 bit image it compiles but I get an AccesViolationException somewhere in the middle of the picture.
 
Any ideas what I did wrong or are there any different approches?
 
I couldn´t find anything here or with google except some article on how to display Raw image data which doesn´t help me in this case as I don´t have that.
 
I hope you guys can help
Johannes
Posted 15-Oct-12 10:27am
Edited 15-Oct-12 23:22pm
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

I finally found the solution!
Because I changed the row from byte to ushort the row has only half the length.
 
so for a 16 bit image the code would look like this:
 
private void ImageEditing()
{            
    //opening a 16 bit per pixel tif image
    Bitmap bmp = new Bitmap("Image.tif");
 
    int Width = bmp.Width;
    int Height = bmp.Height;
 
    //creating the bitmapdata and lock bits
    System.Drawing.Rectangle rec = new System.Drawing.Rectangle(0, 0, Width, Height);
    BitmapData bmd = bmp.LockBits(rec, ImageLockMode.ReadOnly, bmp.PixelFormat);
 
    unsafe
    {
        //iterating through all the pixels in y direction
        for (int y = 0; y < Height; y++)
        {
            //getting the pixels of current row
            ushort* row = (ushort*)bmd.Scan0 + (y * bmd.Stride / 2);
 
            //iterating through all the pixels in x direction
            for (int x = 0; x < Width; x++)
            {
                //getting index of current pixel (3 because of the 3 * 16bits per pixel)
                int index = x * 3;
 
                //getting R, G and B values
                ushort R = row[index + 2];
                ushort G = row[index + 1];
                ushort B = row[index];
            }
        }
    }
 
    //unlocking bits and disposing image
    bmp.UnlockBits(bmd);
    bmp.Dispose();
}
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

The code is basically correct, but it cannot universally work, just because all your shifts will depends on pixel format, which you never use. You only transparently pass bmp.PixelFormat as a parameter to a new bitmap. The code cannot work correctly unless you analyze the value of System.Drawing.PixelFormat (you might need to use if or switch) and shift your pointer arithmetic accordingly. Please see:
http://msdn.microsoft.com/en-us/library/system.drawing.image.pixelformat.aspx[^],
http://msdn.microsoft.com/en-us/library/system.drawing.imaging.pixelformat.aspx[^].
 
—SA
  Permalink  
Comments
BillyTheKid-90 at 16-Oct-12 4:15am
   
Hi Sergey, thanks for your help! I am aware of the Pixelformat and in my universal code I do use it. But in this case, if I change from byte to ushort I still have a pixelsize of 3 if I´m not wrong.
Sergey Alexandrovich Kryukov at 16-Oct-12 12:22pm
   
You see, absolutely regardless of concrete calculations: if you have some bitmap calculations for one Bits-Per-Pixel format, and try to use the same code to different amount of pixels, that code would not do the same thing, unless it has "switch" or "if" branches with shifting bits by different step per pixel, depending on the value of this enumerator, not matter what else you do. Isn't that logical? --SA
BillyTheKid-90 at 16-Oct-12 16:53pm
   
Hi Sergey, as I said, in my universal code I do switch between the various pixelformats. This is just a simplified version only for 8bit images without alpha channel. I also have found the solution by now and posted it here. if I change the code from byte to ushort and then only take one row with BitmapData.Stride/2 it works. because this stride value is calculated in bytes and I use ushorts it´s only half the length. And that´s where the AccessViolation happened, I simply used a too long row.
Sergey Alexandrovich Kryukov at 16-Oct-12 16:59pm
   
Well, then I don't know what's the problem. If you are showing a simplified version, but the essence of the problem is in full version... what sense it should make? What you say now sounds like a correct solution. --SA
BillyTheKid-90 at 16-Oct-12 17:03pm
   
the problem also occurred in the simplified version otherwise it wouldn´t have made much sense... and the solution is correct as I successfully tested it

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 838
1 OriginalGriff 461
2 Tadit Dash 355
3 sanket saxena 329
4 Peter Leow 228
0 Sergey Alexandrovich Kryukov 11,990
1 OriginalGriff 7,349
2 Peter Leow 5,003
3 Abhinav S 4,003
4 Maciej Los 3,575


Advertise | Privacy | Mobile
Web04 | 2.8.140421.2 | Last Updated 16 Oct 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Use
Layout: fixed | fluid