Click here to Skip to main content
15,881,248 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello everybody. I struggle to understand why this is throwing me an error while saving created bitmap. Could anybody help with the following code?

C#
Bitmap ^a=gcnew Bitmap(width,height,System::Drawing::Imaging::PixelFormat::Format16bppGrayScale);
    int i,j;
    BitmapData ^bitmapData=gcnew BitmapData();
    float value;
    System::Drawing::Rectangle b(0,0,width,height);
    a->LockBits(b, System::Drawing::Imaging::ImageLockMode::WriteOnly, a->PixelFormat, bitmapData);
    unsigned short int *ptr=(unsigned short int*)bitmapData->Scan0.ToPointer();
    int stride=bitmapData->Stride;

    for (i=0;i<height;i++)
    {
        unsigned short int * LinePtr = ptr + (i * height);
        for(j=0;j<width;j++)
        {
            //value=mat[j][i];
            LinePtr[j]=0;//65535*value/255;
        }
    }
    a->UnlockBits(bitmapData);
    return a;
Posted
Updated 25-Nov-11 8:44am
v2

Hmm just now a realized something. Image stride for height 600 is 1600 while 1600/600 is not decimal number.And 16bpp should produce stride 600*2 in bytes equals 1200. Am i right ? So i guess bitmap class is putting some "imaginary" pixel data at the end of each scan line maybe for performance reasons? But I still dont know what to do with that ...
 
Share this answer
 
v2
Comments
Mark Salsbery 25-Nov-11 18:52pm    
Last time I checked, that pixel format isn't supported so to even get that far is lucky. Just always use the stride returned by the system :)
Mark Salsbery 26-Nov-11 11:05am    
and this

LinePtr = ptr + (i * height);

should be something like this

LinePtr = ptr + (i * stride);
thanks for help however that's not the case , of course my first guess was LinePtr = ptr + (i * stride); however stride is one row in bytes and since my variable is typed short int which have 3 bytes than for that purpose i*height seemed right answer neither is working. What i am doing now is that i have 24 bpp rgb image and i put same number in each "color slot" now thats not very elegant and it takes time. What would be the better way ?
 
Share this answer
 
v2
Comments
Mark Salsbery 27-Nov-11 14:40pm    
>>"and since my variable is typed short int"

Sorry about that. Regardless, you HAVE to use the data pointer and stride values returned by lockbits. You can't assume anything. The stride can even be negative. So use stride/2 (When using pointer arithmetic I prefer to use Byte* then cast to an Int16* in the inner loop, but that's just me). 16bppgrayscale is not supported anyway (or has very limited support) so you may still struggle with that!
Negative ?? Do i understand it correctly? How can amount of information in bytes be negative. So i guess than there is no better way to code grayscale than to write to rgb same value in each Chanel. Pity ... thanks anyway
 
Share this answer
 
Yes the stride can be negative. One problem in your code, however, is you're not using the correct LockBits method. You're using the one marked "This version of the LockBits method is intended to be used with a flags value of ImageLockMode::UserInputBuffer".

Maybe try this, adjusted to use correct pointer arithmetic and LockBits method...
C++
Bitmap ^a = gcnew Bitmap(width,height,System::Drawing::Imaging::PixelFormat::Format16bppGrayScale);
//float value;
System::Drawing::Rectangle b(0,0,width,height);
BitmapData ^bitmapData = a->LockBits(b, System::Drawing::Imaging::ImageLockMode::WriteOnly, a->PixelFormat);
unsigned char *ptr = (unsigned char *)bitmapData->Scan0.ToPointer();

for (int i = 0;i < height; i++)
{
    unsigned short int * LinePtr = (unsigned short int *)(ptr + (i * bitmapData->Stride));
    for(int j = 0; j < width; j++)
    {
        //value=mat[j][i];
        LinePtr[j]=0;//65535*value/255;
    }
}

a->UnlockBits(bitmapData);
return a;
 
Share this answer
 
v2
well nothing seem to work just fine so i guess i am stuck with 24bpp rgb, thanks for help anyway , much appreciated
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900