Ich habe eine .DLL zu Testzwecken erhalten. Diese .dll enthält die Funktionalität, die später zur Verarbeitung von Livebildern von der Hardware verwendet wird.Bitmap von .DLL abrufen, in Byte [] konvertieren und zu Image
Für diese einfache .dll kann ich ein Bild öffnen (in Arbeitsspeicher laden), die Breite und Höhe abrufen und die Pixel abrufen, die in ein Bild konvertiert werden müssen. Laden, Breite bekommen und Höhe bekommen ist in Ordnung, aber die Pixel zu bekommen und diese in eine Bitmap oder ein Bild zu konvertieren ist ein Problem.
C++ Beispiel Quelle, die ich erhielt:
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;
}
Wo in ApiFunc, diese zu finden sind:
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();
}
So, jetzt, was ich bisher versucht, ich habe versucht, byte [mit ] als Rückgabeparameter, aber das wirft eine 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);
}
}
Antwort Quellen:
answer 1, using bitmap.LockBits method answers 2 and 3, using memoryStream
Nur um sicherzustellen, dass ich ein gültiges Bild mit zu testen, habe ich ein Bild in Photoshop gespeichert, die mit dieser Option:
hässliches Testbild:
Schön ist es nicht? :)
Auch versucht mit einer for-Schleife, und laufen, bis es abstürzt. lief bis count = 1441777 und auf einer anderen Bildanzahl = 1527793 (gleiche Abmessungen).
Vielen Dank! Ich wollte gerade eine Antwort posten, die die gleiche Schleife macht wie sie, aber eine solche Bitmap zu erstellen, scheint ein bisschen intensiv zu sein. von 341ms bis 11ms, indem ich das zuerst mache und dann dem Rest meiner Lösung folge – CularBytes