E 'possibile BitBlt direttamente da una bitmap GDI +?
Domanda
E 'possibile utilizzare BitBlt per copiare direttamente da una bitmap GDI + senza usare GetHBitmap?
GetHBitmap è lento perché rende una nuova copia dell'intera immagine, in aggiunta e più lento rispetto alla copia BitBlt, e la data HBITMAP deve essere smaltito. L'immagine è grande.
C'è un modo per puntare BitBlt per utilizzare i dati dei pixel del GDI originale + immagine?
Modifica che posso ottenere l'indicazione di dove i dati GDI + bitmap pixel è nella memoria. Posso creare un HBITMAP che punta ai dati GDI + bitmap pixel per evitare la copia extra, e BitBlt da questo?
Soluzione
Dopo aver cercato per giorni, improvvisamente mi ha colpito che la risposta mi aveva fissando in tutta la faccia il tempo! Stavo creando un GDI + bitmap da un puntatore a un array di byte. Poi cercando di creare un HBITMAP utilizzando lo stesso puntatore. Ma potrei altrettanto facilmente creare il HBITMAP prima e utilizzare il puntatore da quello per creare la bitmap GDI +.
Funziona come un fascino! È possibile combinare le operazioni GDI e GDI + come più vi piace. L'immagine è al tempo stesso semplice GDI e GDI + in una sola volta. Invece di usare DrawImage, è possibile BitBlt dai dati esatti stesso pixel!
Ecco il codice:
// Create the HBITMAP
BITMAPINFO binfo = new BITMAPINFO();
binfo.biSize = (uint)Marshal.SizeOf(typeof(BITMAPINFO));
binfo.biWidth = width;
binfo.biHeight = height;
binfo.biBitCount = (ushort)Image.GetPixelFormatSize(pixelFormat);
binfo.biPlanes = 1;
binfo.biCompression = 0;
hDC = CreateCompatibleDC(IntPtr.Zero);
IntPtr pointer;
hBitmap = CreateDIBSection(hDC, ref binfo, 0, out pointer, IntPtr.Zero, 0);
// Create the GDI+ bitmap using the pointer returned from CreateDIBSection
gdiBitmap = new Bitmap(width, height, width * binfo.biBitCount >> 3, pixelFormat, pointer);