从CUDA中的指针加载图像并导出dll



我是这类东西的新手。我正在尝试创建一个函数,它相当于图像的直方图函数。我使用windows窗体应用程序来显示直方图(并加载图像)和CUDA/c++来制作直方图。我从一开始就提到,我没有使用openCV、glut、OpenGL或任何其他第三个库。继续…我正在尝试将位图传递到非托管的c++DLL。这里的问题是,我现在不知道如何在c++代码中引用位图。(甚至还有如何从中获得RGB)。代码段:

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导入:

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
}

好吧,经过两个小时的谷歌搜索、堆叠和微软文档整理,我终于找到了一些东西!

因为你使用的是CUDA,我认为你只想要快速而好的解决方案,这就是为什么我试图找到一种方法,你可以在不复制数据的情况下修改数据,只因为C#和C++连接。

到目前为止,我就是这么做的。

有些事情很重要。我使用了一个整数指针,这与当前代码有点混乱。当然,您可以使用一个更有意义的char指针(还没有测试过)。另一件事是System.Drawing.Imaging.PixelFormat。知道自己选择了哪一个真的很重要。在我的示例中,我选择了PixelFormat.Format32bppRgb。字节顺序(到目前为止我已经知道)就是名称的顺序

示例:

32bppRgb代表红色、绿色和蓝色,它们分别消耗8位。然而,因为它是这种格式,而不是24bppRgb,所以它会消耗一个完整的整数(不使用8位)。在这种情况下,不使用前8位(从左到右思考),因此要将像素设置为红色,其工作方式如下。(很抱歉格式化没有按预期工作…)

|8|8|8|3|消耗位

|空|红|绿|蓝|彩色

|00|FF|00|00|红色的颜色代码

红色的代码是这样的=>0x00 FF 00 00十进制为16711680。这就是C++中的数字的来源。

C++代码:

头文件"NativeLibrary.h":

namespace NativeLibrary
{
extern "C" __declspec(dllexport) void __stdcall PassBitmap(int* number, int size);
}

Cpp文件"NativeLibrary.Cpp":

#include <NativeLibrary.h>
void NativeLibrary::PassBitmap(int* number, int size) {
for (int i = 0; i < size; i++) {
number[i] = 16711680;
}
}

C#代码:

using System.Drawing;
using System.Runtime.InteropServices;
[DllImport("NativeLibrary.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void PassBitmap(IntPtr bmp, int size);
public System.Drawing.Bitmap bitmap = null;

public void GenerateAndModifyBitmap()
{
//The pixel format is essential!
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(100, 100, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
//Just which region we want to lock of the bitmap
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(new System.Drawing.Point(), bmp.Size);
//We want to read and write to the data, pixel format stays the same (anything else wouldn't make much sense)
System.Drawing.Imaging.BitmapData data = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
//This is a pointer to the data in memory. Can be manipulated directly!
IntPtr ptr = data.Scan0;
// This code is specific to a bitmap with 32 bits per pixels.
// Ignore current calculations. They are still work in progress xD
int size = bmp.Height;
size *= Math.Abs(data.Stride);
size /= 4;
//Call native function with our pointer to the data and of course how many ints we have
PassBitmap(ptr, size);
//Work is finished. Give our data back to the manager
bmp.UnlockBits(data);
bitmap = bmp;
}

此代码将生成一个完全红色的位图。

相关内容

  • 没有找到相关文章

最新更新