2017-01-05 2 views
0

나는 이런 종류의 물건에 익숙하지 않습니다. 이미지의 히스토그램 함수에 해당하는 함수를 만들려고합니다. 히스토그램을 표시하고 이미지를로드하는 Windows 양식 응용 프로그램과 히스토그램을 작성하는 CUDA/C++을 사용하고 있습니다. OpenCV, glut, OpenGL 또는 다른 세 번째 라이브러리를 사용하지 않는다는 것을 처음부터 언급하고 있습니다. Carrying on ... 비 관리 C++ DLL에 비트 맵을 전달하려고합니다. 여기서 문제는 C++ 코드에서 해당 비트 맵을 참조하는 방법이 아니라는 것입니다. (그리고 RGB를 얻는 방법조차도). 코드의 조각 :dll 내보내기로 CUDA의 포인터에서 이미지로드

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++ : 나는 인터넷 검색을 stackoverflowing 2 시간 후에 뭔가를했다

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 
} 
+0

나는 이걸 파고 있습니다. –

+0

내 대답이 사람들을 도와 줄 수 있기를 바랍니다 :)! 그 질문에 너무 감사드립니다. 이제는 C++로하는 법을 배웠습니다 : D –

답변

1

좋아하고 마이크로 소프트 문서화!

당신이 CUDA를 사용하고 있기 때문에 빠르고 좋은 솔루션만을 원한다고 생각합니다. 그래서 C# 및 C++ 연결 때문에 여러 번 복사하지 않고 데이터를 수정할 수있는 방법을 찾으려고했습니다.

그건 내가 지금까지 해왔습니다.

몇 가지 사항이 중요합니다. 정수 포인터를 사용했습니다. 현재 코드에서 약간 지저분합니다. 물론 훨씬 더 의미있는 char 포인터를 사용할 수 있습니다 (테스트하지 않았습니다). 또 다른 것은 System.Drawing.Imaging.PixelFormat입니다. 당신이 선택한 것을 아는 것이 정말로 중요합니다. 내 예에서는 PixelFormat.Format32bppRgb을 선택했습니다. 바이트 순서는 (지금까지 나는 배웠습니다) 이름이 어떻게 지는지입니다.

예 :

32bppRgb8 비트 소비 적색, 녹색 및 청색 약자. 그러나이 형식이 아니기 때문에 24bppRgb이 사용됩니다 (8 비트는 사용되지 않음). 이 경우에는 처음 8 비트가 사용되지 않습니다 (왼쪽에서 오른쪽으로 생각). 이렇게 픽셀을 빨강으로 설정하면 이처럼 작동합니다. (미안 포매팅이 예상대로 작동하지 않았습니다 ...)

| 8 | 8 | 8 | 8 | 소모 비트

| 비어 있음 | 빨간색 | 녹색 | 파란색 | 색상

| 00 | FF | 00 | 00 |

빨간색

의 색상 코드는 그래서 빨간색의 코드는이 => × 00 FF 00 00 이며이 16711680.을의 진수로 C++의 숫자가 어디에서 오는지 있다고.

C++ 코드 :

헤더 파일 "NativeLibrary.시간 "

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; 
} 

이 코드는 완전히 빨간색 비트 맵을 생성합니다.

+0

고마워요! 니가 끝냈어!! –

+0

하하 많이 감사합니다. D. 이 질문에 따라 남겨진 것이 있다면 언제든지 의견을 말하십시오. 나는 단지 재주를 생각하고있다. –