ibezito
ibezito

Reputation: 5822

bitmap visualization issues when returning from C++ to C# layer

I'm trying to create a Bitmap in c# app layer, filling it on C++ layer with OpenCV, and displaying it back in c#.

This leads to visualization issues. I wrote a simplified code which demonstrates the problem.

Results

enter image description here

My code

C# app:

int width = 640, height = 480;
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadWrite,
     System.Drawing.Imaging.PixelFormat.Format8bppIndexed);

CppWrapper.fillImage((byte*)bmpData.Scan0.ToPointer(), width, height, bmpData.Stride);
bitmap.Save("filledBitmap.bmp", ImageFormat.Bmp);

C# wrapper:

[DllImport("CppWrapperLib.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
    public static unsafe extern void fillImage(byte* im, int width, int height, int stride);

C++ Layer:

void __stdcall fillImage(byte* im, int width, int height, int stride)
{
    cv::Mat mat(cv::Size(width, height), CV_8UC1, im, stride);

    mat.setTo(0);
    cv::circle(mat, cv::Point(width / 2, height / 2), 50, 255,-1);
    cv::circle(mat, cv::Point(width / 2, height / 2), 40, 180, -1);
    cv::circle(mat, cv::Point(width / 2, height / 2), 30, 150, -1);
    cv::circle(mat, cv::Point(width / 2, height / 2), 20, 120, -1);
    cv::circle(mat, cv::Point(width / 2, height / 2), 10, 80, -1);
}

Thanks!

Upvotes: 1

Views: 100

Answers (1)

Stefan
Stefan

Reputation: 17658

update: I couldn't find any default palette which corresponds with your numbers, since I don't have time at this moment to generate an image myself, I'll post an update with the default palette numbering later. Nevertheless, you seem to be facing a palette issue.

It looks like you are using a 8-bit gray-scale.

In that case you'll need to override the default palette.

//C# part 
ColorPalette palette = bitmap.Palette;
for (int c = 0; c <= 255; c++)
    palette .Entries[c] = Color.FromArgb(255, c, c, c);

bitmap.Palette = palette;

note Since you are saving the bitmap I am not sure if the palette is saved with the bitmap by default.

By default the 8-bit palette is set to the old VGA colorspace:

enter image description here

Some difference between MAC and windows:

http://www.columbia.edu/itc/visualarts/r4110/f2000/week06/06_03_Color_palettes.pdf

Upvotes: 1

Related Questions