¿cómo gestionaría la representación píxel por píxel en WPF (como, por ejemplo, para un raytracer)? Mi conjetura inicial fue crear un BitmapImage, modificar el búfer y mostrarlo en un control de imagen, pero no pude encontrar cómo crear uno (el método create requiere un bloque de memoria no administrada)Píxeles de dibujo en WPF
Respuesta
le recomiendo contra las dos sugerencias anteriores. The WriteableBitmap class proporciona lo que necesita suponiendo que está utilizando 3.5 SP1. Antes de SP1 no hay una respuesta realmente buena a esta pregunta en WPF a menos que recurras a algún truco serio.
podrías colocar 1X1 rectángulo objetos en un lienzo
private void AddPixel(double x, double y)
{
Rectangle rec = new Rectangle();
Canvas.SetTop(rec, y);
Canvas.SetLeft(rec, x);
rec.Width = 1;
rec.Height = 1;
rec.Fill = new SolidColorBrush(Colors.Red);
myCanvas.Children.Add(rec);
}
que deberían estar bastante cerca de lo que desea
se pueden añadir pequeñas rectas si lo desea, pero cada uno de ellos es un FrameworkElement, por lo que es probable que un peso pesado poco. La otra opción es crear usted mismo un DrawingVisual, dibujar en ella, hacerla a continuación pegarlo en una imagen:
private void DrawRubbish()
{
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
Random rand = new Random();
for (int i = 0; i < 200; i++)
dc.DrawRectangle(Brushes.Red, null, new Rect(rand.NextDouble() * 200, rand.NextDouble() * 200, 1, 1));
dc.Close();
}
RenderTargetBitmap rtb = new RenderTargetBitmap(200, 200, 96, 96, PixelFormats.Pbgra32);
rtb.Render(dv);
Image img = new Image();
img.Source = rtb;
MainGrid.Children.Add(img);
}
gran solución. Trabajado como un encanto. Solo una pequeña cosa: dc.Close(); no es necesario. Usando llamadas Dispose(), que está haciendo lo mismo que Close(). Comprobé el código fuente de WPF :-) –
Si está pensando en hacer algo así como un rastreador de rayos en el que necesitará trazar muchos puntos, probablemente querrá dibujar en el espacio de memoria del mapa de bits directamente en lugar de atravesar las capas de abstracción. Este código le dará tiempos de renderización significativamente mejores, pero tiene el costo de necesitar un código "inseguro", que puede o no ser una opción para usted.
unsafe
{
System.Drawing.Point point = new System.Drawing.Point(320, 240);
IntPtr hBmp;
Bitmap bmp = new Bitmap(640, 480);
Rectangle lockRegion = new Rectangle(0, 0, 640, 480);
BitmapData data = bmp.LockBits(lockRegion, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte* p;
p = (byte*)data.Scan0 + (point.Y * data.Stride) + (point.X * 3);
p[0] = 0; //B pixel
p[1] = 255; //G pixel
p[2] = 255; //R pixel
bmp.UnlockBits(data);
//Convert the bitmap to BitmapSource for use with WPF controls
hBmp = bmp.GetHbitmap();
Canvas.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hbmpCanvas, IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
Canvas.Source.Freeze();
DeleteObject(hBmp); //Clean up original bitmap
}
Para limpiar el hBitmap tendrá que declarar esta cerca de la parte superior de su archivo de clase:
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
También tenga en cuenta que tendrá que establecer las propiedades del proyecto para permitir código no seguro. Puede hacer esto haciendo clic derecho en el proyecto en el explorador de soluciones y seleccionando propiedades. Ir a la pestaña Construir Marca la casilla "Permitir código no seguro". También creo que deberá agregar una referencia a System.Drawing.
Muchas gracias por esta solución. –
Aquí hay un método que usa WritableBitmap.
public void DrawRectangle(WriteableBitmap writeableBitmap, int left, int top, int width, int height, Color color)
{
// Compute the pixel's color
int colorData = color.R << 16; // R
colorData |= color.G << 8; // G
colorData |= color.B << 0; // B
int bpp = writeableBitmap.Format.BitsPerPixel/8;
unsafe
{
for (int y = 0; y < height; y++)
{
// Get a pointer to the back buffer
int pBackBuffer = (int)writeableBitmap.BackBuffer;
// Find the address of the pixel to draw
pBackBuffer += (top + y) * writeableBitmap.BackBufferStride;
pBackBuffer += left * bpp;
for (int x = 0; x < width; x++)
{
// Assign the color data to the pixel
*((int*)pBackBuffer) = colorData;
// Increment the address of the pixel to draw
pBackBuffer += bpp;
}
}
}
writeableBitmap.AddDirtyRect(new Int32Rect(left, top, width, height));
}
y utilizarla:
private WriteableBitmap bitmap = new WriteableBitmap(1100, 1100, 96d, 96d, PixelFormats.Bgr24, null);
private void Button_Click(object sender, RoutedEventArgs e)
{
int size = 10;
Random rnd = new Random(DateTime.Now.Millisecond);
bitmap.Lock(); // Lock() and Unlock() could be moved to the DrawRectangle() method. Just do some performance tests.
for (int y = 0; y < 99; y++)
{
for (int x = 0; x < 99; x++)
{
byte colR = (byte)rnd.Next(256);
byte colG = (byte)rnd.Next(256);
byte colB = (byte)rnd.Next(256);
DrawRectangle(bitmap, (size + 1) * x, (size + 1) * y, size, size, Color.FromRgb(colR, colG, colB));
}
}
bitmap.Unlock(); // Lock() and Unlock() could be moved to the DrawRectangle() method. Just do some performance tests.
image.Source = bitmap; // This should be done only once
}
- 1. Plano rápido de píxeles en WPF
- 2. Elipse Dibujo Animación WPF
- 3. Ejemplo de dibujo de píxeles OpenGL/PBO necesario
- 4. Elegir entre Dibujo y Forma en WPF
- 5. ¿Cómo usar el dibujo GDI + en WPF?
- 6. ¿Cómo convierto un tamaño de WPF en píxeles físicos?
- 7. Dispositivo independiente de píxeles
- 8. Eficacia del sombreado de píxeles suma de todos los píxeles
- 9. flechas dibujo con datos de la trayectoria WPF
- 10. Imagen WPF, cambiando el color de los píxeles
- 11. Dibujar con el mouse provoca huecos entre los píxeles
- 12. Dibujo WPF que se extiende sin estirar la pluma
- 13. Dibujo de lienzo y pantalla Retina: ¿realizable?
- 14. Establecer píxeles individuales en .NET Format16bppGrayScale image
- 15. Dibujo multiproceso en .NET?
- 16. dibujo en iphone
- 17. Dibujo hueco en iPhone
- 18. C# Dibujo en Paneles
- 19. Dibujo en MKOverlay personalizado
- 20. gráficos de dibujo en Django
- 21. píxeles en Direct2D
- 22. document.execCommand() FontSize en píxeles?
- 23. coordenadas de píxeles en diamante
- 24. ¿Hay alguna manera de cambiar el orden de dibujo en WPF
- 25. android: measureText() Devuelve píxeles basados en píxeles escalados
- 26. Convertir el formato de píxeles de WriteableBitmap a Bgra32 en C# wpf
- 27. Creación y dibujo de imágenes enormes (en búfer) en Java
- 28. Qt/C++: dibujo eficientemente
- 29. ¿Cómo puedo estirar el mapa de bits en WPF sin suavizar píxeles?
- 30. Animación de dibujo
La clase WriteableBitmap está disponible desde .NET 3.0 y esta es la primera versión de WPF. No necesita .NET 3.5 para usar esta clase. –