Domanda

Mi piacerebbe fare un po 'di elaborazione di immagini in un'applicazione WPF. Tuttavia, vorrei modificare i pixel di un BitmapSource in memoria in fase di esecuzione.

Attualmente sto riuscendo a fare questo codice usando 'non sicuro' contro un vecchio System.Drawing.Bitmap stile e funziona un ossequio (bloccare un area di lavoro, violino con i pixel) lavoro fatto. L'approccio è descritto in questo post: http://blogs.msdn.com/b/ericgu/archive/2007/06/20/lost-column-2-unsafe-image-processing.aspx

Per ottenere questo lavoro in WPF Sto quindi la creazione di un WPF BitmapSource utilizzando questo approccio:

    BitmapSource destination;
    IntPtr hBitmap = bitmap.GetHbitmap();
    BitmapSizeOptions sizeOptions = BitmapSizeOptions.FromEmptyOptions();
    destination = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, sizeOptions);
    destination.Freeze();
    return destination;

Tuttavia, questo crea un sacco di copie in memoria e ho davvero voglia di arrivare lì e violino con i bit sottostanti all'interno del BitmapSource proprio come EricGu mostrato nell'esempio Bitmap. È possibile?

Mi rendo conto che PixelShaders probabilmente può fare questo, ma questo è un esercizio accademico che coinvolge più thread (che è supportato durante la modifica di una bitmap in modalità non sicura).

Grazie in anticipo

È stato utile?

Soluzione

ti dirò quanto ne so.

Per prima cosa sembrano sapere già circa congelamento bitmap prima di dare di nuovo al thread principale. Questo è un buon inizio.

Ho una volta cercato di ridurre la copia derivando una nuova implementazione da BitmapSource, e sostituire le funzioni virtuali che copiare i dati fuori dalla bitmap. Ha funzionato ma produce perdite di memoria di massa. Mai capito.

È possibile anche, naturalmente, creare un BitmapSource direttamente da un array di byte (e perdere sovraccarico di bitmap GDI). MSDN docs

Avete considerato un WriteableBitmap ? Quella era la risposta del team di WPF alla lamentela comune su tutte le copie.

Modifica : MSDN dice esplicitamente (nella documentazione WritableBitmap.BackBuffer), che può essere utilizzato da un thread in background:

  

È possibile passare il puntatore a BackBuffer   componenti esterni e altri thread   per l'elaborazione, ma se lo fai,   deve offrire proprio thread   coordinazione. In particolare, è necessario   assicurare che specifica thread UI   aree mutate chiamando il   Metodo AddDirtyRect, e che l'IU   filo sblocca il buffer chiamando   il metodo di sblocco.

Quindi, se si lascia che la thread UI acquisire il blocco e il puntatore, è possibile lasciare che un thread di lavoro di scrittura dei pixel.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top