I am new to this kind of stuff. I'm trying to create a function which is equivalent to the histogram function of an image. I am using windows forms application to show the histogram (and load the image) and CUDA/c++ to make the histogram. I am mentioning from the beginning that I am NOT using openCV, glut, OpenGL or any other third library. Carrying on... I am trying to pass a bitmap to an unmanaged c++ DLL. The problem here is that I don't now how to reference that bitmap in the c++ code. (And even how to get the RGB out of it). Snippets of code:
c# :
private void calculateHistogram(object sender, EventArgs e)
{
Bitmap bmp = (Bitmap)pictureBox1.Image;
unsafe {
int** matrixAcumulated;
var date = bmp.LockBits(new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
matrixAcumulated=NativeMethods.GenerateHistogram(date.Scan0, pictureBox1.Width);
bmp.UnlockBits(date);
// Write the string to a file.
System.Console.WriteLine(matrixAcumulated[0][0]);
}
}
Dll import :
using System;
using System.Runtime.InteropServices;
namespace HistogramProcessingCs
{
class NativeMethods
{
[DllImport("HistogramProcessingCpp.dll", CallingConvention = CallingConvention.StdCall)]
public static extern unsafe int** GenerateHistogram(IntPtr bmp, int dimensionImage);
}
}
c++ :
extern "C" __declspec(dllexport) int** __stdcall GenerateHistogram(unsigned char *bmp, int dimensionImage)
{
//How to refere the bitmap from the bmp pointer?
//dimensionImage is Width = Height
}
Okay I worked out something after 2 hours of googling, stackoverflowing and microsoft documentationing!
Because you're using CUDA I think you only want fast and nice solutions, that's why I tried to find a way with which you can modify data without copying it many times only because of C# and C++ connection.
That's what I've done so far.
Some things are important. I used an integer pointer, that's a bit messy with the current code. You can of course use instead a char pointer which makes much more sense (haven't tested this). Another thing is the
System.Drawing.Imaging.PixelFormat
. It's really important to know which you have choosen. In my example I've choosenPixelFormat.Format32bppRgb
. The byte order is (so far I learned) just how the name is.Example:
32bppRgb stands for red, green and blue which consume each 8 bits. However because it's this format and not 24bppRgb it consumes a whole integer(8 bits aren't used). In this case the first 8 bits arent used (left to right thinking) so to set a pixel to red it works like this. (Sorry formating didn't worked as expected...)
| 8 | 8 | 8 | 8 | consuming bits
|empty | red | green | blue | color
| 00 | FF | 00 | 00 | color code for red
So the code for red is this => 0x00 FF 00 00 and as decimal it's 16711680. That's where the number in the C++ comes from.
C++ Code:
Header file "NativeLibrary.h":
Cpp file "NativeLibrary.cpp":
C# Code:
This code would generate a bitmap which is completely red.