¿Es posible modificar un WPF BitmapSource en la memoria 'unsafe'ly desde otro hilo
-
29-09-2019 - |
Pregunta
Me gustaría hacer algo de procesamiento de imágenes en una aplicación de WPF. Sin embargo, me gustaría modificar los píxeles de un BitmapSource en memoria en tiempo de ejecución.
Actualmente estoy logrando hacer esto utilizando el código 'insegura' contra un viejo System.Drawing.Bitmap moda y funciona un convite (bloqueo de un área de trabajo, el violín con los píxeles) trabajo. El enfoque se describe en este mensaje: http://blogs.msdn.com/b/ericgu/archive/2007/06/20/lost-column-2-unsafe-image-processing.aspx
Para conseguir este trabajo en WPF Entonces estoy creando un WPF BitmapSource uso de este enfoque:
BitmapSource destination;
IntPtr hBitmap = bitmap.GetHbitmap();
BitmapSizeOptions sizeOptions = BitmapSizeOptions.FromEmptyOptions();
destination = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, sizeOptions);
destination.Freeze();
return destination;
Sin embargo, esto crea una gran cantidad de copias en la memoria y tengo muchas ganas de llegar allí y violín con los bits subyacentes dentro del BitmapSource igual EricGu mostró en el ejemplo de mapa de bits. es posible?
Me doy cuenta de que probablemente PixelShaders pueden hacer esto, pero este es un ejercicio académico que involucra múltiples hilos (que se apoya al editar un mapa de bits en modo no seguro).
Gracias de antemano
Solución
Te diré todo lo que sé.
En primer lugar, parece que ya sabe acerca de congelación mapas de bits antes de dar vuelta al hilo principal. Eso es un comienzo bueno.
Me han tratado de reducir una vez que la copia mediante la derivación de una nueva aplicación de BitmapSource, y anular las funciones virtuales que copian los datos del mapa de bits. Funcionó, pero produce pérdidas de memoria masiva. Nunca descubierto.
También puede, por supuesto, crear una BitmapSource directamente a partir de una matriz de bytes (y los gastos generales perder del mapa de bits GDI). MSDN docs
¿Usted ha considerado un WriteableBitmap ? Esa fue la respuesta del equipo de WPF a la queja común sobre la totalidad de la copia.
Editar : MSDN dice explícitamente (en la documentación WritableBitmap.BackBuffer) que se puede utilizar desde un subproceso de fondo:
Puede pasar el puntero a BackBuffer componentes externos y otros hilos para su procesamiento, pero si lo hace, usted debe proporcionar propio hilo coordinación. En particular, debe asegurar que los especifica hilo UI modificados áreas llamando al método AddDirtyRect, y que la interfaz de usuario hilo desbloquea el tampón llamando el método de desbloqueo.
Así que si usted deja que el hilo de interfaz de usuario adquirir la cerradura y el puntero, puede dejar una escritura subproceso de trabajo de los píxeles.