爲了測試目的,我收到了一個.DLL文件,該.dll文件包含稍後將用於處理來自硬件的實時圖像的功能。從.DLL獲取位圖,轉換爲字節[]和圖像
對於這個簡單的.dll,我可以打開一個圖像(加載到內存中),獲取寬度和高度,並獲取需要轉換爲圖像的像素。加載,獲取寬度和獲取高度是好的,但獲取像素並將其轉換爲位圖或圖像是一個問題。凡在ApiFunc,這可以發現
ApiFunc->OpenImageFile(this->OpenPictureDialog1->FileName.c_str());
ApiFunc->AllocMemory();
w = ApiFunc->GetImageWidth();
h = ApiFunc->GetImageHeight();
Image1->Width = w;
Image1->Height = h;
unsigned char* ptr = ApiFunc->GetImagePixels();
COLORREF pixel;
int r,g,b;
for(int y=0; y<w; y++)
{
for(int x=0; x<h; x++)
{
r = (int)*(ptr+3*x);
g = (int)*(ptr+3*x+1);
b = (int)*(ptr+3*x+2);
Image1->Canvas->Pixels[y][x] = RGB(r,g,b);
}
ptr += 3*h;
}
:我收到
C++示例源
void __fastcall TAPIFunc::LoadDll(HINSTANCE m_hMain)
{
//some others above
GET_IMAGE_PIXELS = (func_GET_IMAGE_PIXELS )GetProcAddress(m_hMain, "GET_IMAGE_PIXELS");
//some others below
}
unsigned char* __fastcall TAPIFunc::GetImagePixels(void)
{
return GET_IMAGE_PIXELS();
}
所以,現在我已經試過到目前爲止,我已經使用字節[嘗試]作爲返回參數,但是會拋出MarshalDirectiveException。
[DllImport("ImageTest.dll")]
public static extern IntPtr GET_IMAGE_PIXELS();
private void OpenImage(string filename)
{
OPEN_IMAGE_FILE(filename);
ALLOC_MEMORY();
int width = GET_IMAGE_WIDTH(); //=800
int height = GET_IMAGE_HEIGHT(); //=600
IntPtr buffer = GET_IMAGE_PIXELS();
int size = width * height * 3;//not sure what the size must be, I think this is one of the issues, just following logic of one answer below.
//but source: https://stackoverflow.com/a/16300450/2901207
byte[] bitmapImageArray = new byte[size];
Marshal.Copy(buffer, bitmapImageArray, 0, size);
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
BitmapData bmData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
IntPtr pNative = bmData.Scan0;
Marshal.Copy(imageData, 0, pNative,size);
bitmap.UnlockBits(bmData);
bitmap.Save(Environment.CurrentDirectory + @"\result.bmp");
using (var ms = new MemoryStream(bitmapImageArray))
{
//both throw exception: Parameter is not valid
Bitmap bmp = new Bitmap(ms);
Image bitmapImage = Image.FromStream(ms);
}
}
答案來源:
answer 1, using bitmap.LockBits method answers 2 and 3, using memoryStream
只是爲了確保我有一個有效的圖像有,我保存在Photoshop的圖像,使用此選項進行測試:
難看的測試圖片:
美麗的,不是嗎? :)
也嘗試使用for循環,並運行,直到它崩潰。跑到計數= 1441777和另一個圖像計數= 1527793(相同的尺寸)。
int count = 0;
for (int i = 0; i < width * height * 4; i++)
{
count++;
bitmapImageArray[i] = Marshal.ReadByte(buffer, i);
}
謝謝!我正要發佈一個與他們做的循環相同的答案,但像這樣構建一個位圖似乎有點密集。先從341毫秒到11毫秒,然後按照我的解決方案 – CularBytes