2008-09-17 12 views

Respuesta

4

Aparece the word is no.


Para referencia futura, tenemos la intención de utilizar un puerto de la Writeable Bitmap Extensions para WPF.

Para una solución puramente utilizando el código existente, cualquiera de las otras sugerencias mencionadas a continuación va a funcionar.

+0

Esa no es una palabra oficial. Es solo un tipo que dice algo en un foro. –

+0

Punto tomado; texto actualizado Supongo que se podría decir que significa "oficial" como en "publicado en un foro supervisado por funcionarios, y no corregido por ellos", pero eso es un poco exagerado :) –

5

me pregunto lo mismo, ya que actualmente hago algo como:

DrawingVisual drawingVisual = new DrawingVisual(); 
using (DrawingContext drawingContext = drawingVisual.RenderOpen()) 
{ 
    // 
    // ... draw on the drawingContext 
    // 
    RenderTargetBitmap bmp = new RenderTargetBitmap(width, height, dpi, dpi, PixelFormats.Default); 
    bmp.Render(drawingVisual); 
    image.Source = bmp; 
} 

estoy tratando de utilizar el WriteableBitmap para permitir el acceso multiproceso en el búfer de píxeles, que en la actualidad no está permitido ni con un DrawingContext ni un RenderTargetBitmap. ¿Tal vez algún tipo de rutina WritePixels basada en lo que has recuperado del RenderTargetBitmap funcionaría?

+0

Render pasar demasiado tiempo – lindexi

+0

Usted no puede escribir el bmp.Render en el uso eso no puede obtener el drawingVisual. – lindexi

15

Si no les importa usar System.Drawing que podría hacer algo como:

var wb = new WriteableBitmap(width, height, dpi, dpi, 
           PixelFormats.Pbgra32, null); 
wb.Lock(); 
var bmp = new System.Drawing.Bitmap(wb.PixelWidth, wb.PixelHeight, 
            wb.BackBufferStride, 
            PixelFormat.Format32bppPArgb, 
            wb.BackBuffer); 

Graphics g = System.Drawing.Graphics.FromImage(bmp); // Good old Graphics 

g.DrawLine(...); // etc... 

// ...and finally: 
g.Dispose(); 
bmp.Dispose(); 
wb.AddDirtyRect(...); 
wb.Unlock();      
+0

No he tenido la oportunidad de probarlo por el momento, pero esto parece una solución muy razonable en WPF. ¡Gracias! –

+1

En caso de que alguien se pregunte, probé el método DrawingVisual WPF mencionado en este tema y este método System.Drawing, y este método System.Drawing es MUCHO MÁS RÁPIDO. Estoy muy decepcionado con WPF. – Verax

+1

Usted puede hacer lo mismo con WPF, con similares prestaciones mediante el uso de RenderTargetBitmap y DrawingVisual/DrawingContext –

19

encontré solución sixlettervariables' la más viable. Sin embargo, falta un "drawingContext.Close()". De acuerdo con MSDN, "Un DrawingContext debe cerrarse antes de que se pueda procesar su contenido". El resultado es la siguiente función de utilidad:

public static BitmapSource CreateBitmap(
    int width, int height, double dpi, Action<DrawingContext> render) 
{ 
    DrawingVisual drawingVisual = new DrawingVisual(); 
    using (DrawingContext drawingContext = drawingVisual.RenderOpen()) 
    { 
     render(drawingContext); 
    } 
    RenderTargetBitmap bitmap = new RenderTargetBitmap(
     width, height, dpi, dpi, PixelFormats.Default); 
    bitmap.Render(drawingVisual); 

    return bitmap; 
} 

Esto puede fácilmente ser utilizada como esta:

BitmapSource image = ImageTools.CreateBitmap(
    320, 240, 96, 
    drawingContext => 
    { 
     drawingContext.DrawRectangle(
      Brushes.Green, null, new Rect(50, 50, 200, 100)); 
     drawingContext.DrawLine(
      new Pen(Brushes.White, 2), new Point(0, 0), new Point(320, 240)); 
    }); 
+4

El '.Close()' es implícita en el '.Dispose()' (o mejor?) - que es el punto entero detrás la declaración 'using'. Si deja * solo * el comando 'render (...)' dentro del bloque de uso, estará bien y no necesita '.Close()'. –

+0

Gracias Eamon. Solucioné el error en el código. –

+4

No hay 'WriteableBitmap' en esta respuesta, ¿por qué es el más alto? :) No tiene relación con la pregunta. –

1

Una forma diferente de resolver este problema es utilizar un RenderTargetBitmap como un almacén de respaldo, simplemente como en el ejemplo WriteableBitmap. Luego puede crear y emitir comandos de dibujo de WPF cuando lo desee. Por ejemplo:

// create the backing store in a constructor 
var backingStore = 
     new RenderTargetBitmap(200,200,97,97,PixelFormats.Pbgra32); 
myImage.Source = backingStore; 

// whenever you want to update the bitmap, do: 
var drawingVisual = new DrawingVisual(); 
var drawingContext = drawingVisual.RenderOpen(); 
{ 
    // your drawing commands go here 
    drawingContext.DrawRectangle(
      Brushes.Red, new Pen(), 
      new Rect(this.RenderSize)); 
} 
Render(drawingContext); 
drawingContext.Close(); 
backingStore.Render(drawingVisual); 

Si desea volver a dibujar este RenderTargetBitmap cada cuadro, se puede coger el evento CompositionTarget.Rendering, así:

CompositionTarget.Rendering += MyRenderingHandler; 
Cuestiones relacionadas