2010-03-16 7 views
11

Sto scrivendo un'applicazione WPF che utilizza un componente e questo componente restituisce un puntatore (IntPtr) ai pixel di una bitmap (altezza * della falcata). So in anticipo che la bitmap è un 24 bit RGB, la sua larghezza e altezza.WPF: Come aggiornare un'immagine in modo efficiente 30 volte al secondo

L'aggiornamento del controllo Immagine con questi bitmap costituisce un video per l'utente, ma non sono sicuro quale sia il modo più efficiente per farlo, il più delle volte l'utilizzo della CPU va al 75% + e la memoria cambia da Da 40mb a 500mb e il nI pensa che GC inizi a funzionare e poi ridiscenda a 40mm. L'app inizia a non essere reattiva.

Cosa devo fare?

grazie!

risposta

14

Probabilmente stai allocando nuove Bitmap, che non sono usa e getta. Dovresti assegnare un singolo WriteableBitmap e aggiornarlo. La documentazione collegata descrive il processo dietro di blocco, l'aggiornamento, e lo sblocco di un WriteableBitmap

Il software lavoro sull'utilizzo di immagini ecografiche in tempo reale in WPF, sto ricevendo un Windows Form Bitmap, che copio nella WriteableBitmap direttamente utilizzando il CopyMemory nativo metodo. Anche con questo lavoro più complicato, la CPU non è eccessivamente tesa e l'utilizzo della memoria non si sposta mai fino a quando dispongo correttamente di ciò che posso. Speriamo che questo esempio può aiutare a:

// DLL returns images as a WinForms Bitmap 
Bitmap bmp = myClass.getWinFormsBitmap(); 

// In my situation, the images are always 640 x 480. 
BitmapData data = bmp.LockBits(new Rectangle(0, 0, 640, 480), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); 
this.writeableBitmap.Lock(); 

// Copy the bitmap's data directly to the on-screen buffers 
NativeMethods.CopyMemory(this.writeableBitmap.BackBuffer, data.Scan0, ImageBufferSize); 

// Moves the back buffer to the front. 
this.writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, 640, 480)); 
this.writeableBitmap.Unlock(); 

bmp.UnlockBits(data); 

// Free up the memory of the WinForms bitmap 
bmp.Dispose(); 

Dove CopyMemory è definito come:

[DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory")] 
public static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length); 
+0

testarlo e farti sapere, grazie! – John

+0

fantastico !! funziona alla grande grazie! – John

+0

perché non stai usando il metodo WritePixels su WriteableBitmap? Solo se c'è una ragione specifica. – nietras

4

Utilizzando il metodo comodo chiamato WritePixels su WriteableBitmap possiamo scrivere un po 'più corto in questo modo:

// DLL returns images as a WinForms Bitmap 
// It's disposed even if an exception is thrown 
using (Bitmap bmp = myClass.getWinFormsBitmap()) 
{ 
    // In my situation, the images are always 640 x 480. 
    BitmapData data = bmp.LockBits(new Rectangle(0, 0, 640, 480), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); 
    writeableBitmap.WritePixels(new Int32Rect(0, 0, 640, 480), data.Scan0, ImageBufferSize, data.Stride); 
    bmp.UnlockBits(data); 
} 
Problemi correlati