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.