我將如何管理WPF中的逐像素渲染(例如,對於光線追蹤器)?我最初的猜測是創建一個BitmapImage,修改緩衝區,並顯示在一個Image控件,但我不知道如何創建一個(創建方法需要一個非管理內存塊)在WPF中繪製像素
回答
我強烈建議對前兩個建議。假設您使用3.5 SP1,The WriteableBitmap class提供了您需要的內容。在SP1之前,除非你訴諸一些嚴重的欺騙,否則在WPF中這個問題沒有很好的答案。
你可以放置1X1矩形對象到畫布上
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);
}
這應該是相當接近你想要
您可以添加小rects如果你想要的,但每一類又是一個FrameworkElement的是什麼,所以它可能是一個有點重量級。另一種選擇是創建自己DrawingVisual,借鑑它,使它然後堅持它的圖像:
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);
}
的最佳解決方案。像魅力一樣工作。只有一件小事: dc.Close();不需要 。使用調用Dispose(),它和Close()一樣。我檢查了WPF源代碼:-) – 2016-01-03 18:12:33
如果您正在考慮做類似光線追蹤的事情,您需要繪製很多點,您可能需要直接在位圖的內存空間中繪製點,而不是通過抽象層。這段代碼會給你提供更好的渲染時間,但是它的代價是需要「不安全」的代碼,這可能或可能不適合你。
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
}
要清理HBITMAP你需要聲明這附近你的類文件的頂部:
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
另外請注意,您將需要設置項目屬性,允許不安全的代碼。您可以通過右鍵單擊解決方案資源管理器中的項目並選擇屬性來完成此操作。轉到生成選項卡。選中「允許不安全的代碼」框。另外我相信你需要添加一個對System.Drawing的引用。
非常感謝這個解決方案。 – 2010-10-13 12:32:15
這是一個使用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));
}
,並使用它:
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. 如何在WPF中繪製像素
- 2. WPF中的快速像素繪製
- 3. 繪製像素
- 4. 在Java中繪製像素圖像
- 5. 如何以像素爲單位在WPF中繪製
- 6. 在UI元素頂部繪製WPF
- 7. 如何繪製座標[0; 1]而不是WPF中的像素?
- 8. 在Quartz中繪製單個像素
- 9. 如何在XNA中繪製2D像素?
- 10. 在JavaFX中繪製子像素?
- 11. 在OpenGL中繪製單個像素
- 12. 在OpenGL中繪製大量像素
- 13. 在JFrame Swing中繪製像素
- 14. 在R中繪製體素圖像
- 15. 如何在SDL 2.0中繪製像素?
- 16. 在wpf中繪製圖表
- 17. 在WPF中繪製數字
- 18. 在WPF中繪製3D線
- 19. 在WPF中繪製地圖
- 20. 使用XCode繪製像素
- 21. 繪製像素 - Objective-C/Cocoa
- 22. 按像素繪製pyglet(python)
- 23. 像素繪製算法
- 24. 如何在WPF中的1像素厚的畫布上繪製線條
- 25. 我怎樣才能讓DrawGeometry在WPF中繪製設備像素線?
- 26. iOS中繪製像素陣列
- 27. 在SDL_Surface像素上繪製矩形
- 28. 在畫布上繪製像素橢圓
- 29. 在QPixmap上繪製的奇怪像素
- 30. VB.NET繪製圖像(組像素)
WriteableBitmap類自.NET 3.0起可用,這是WPF的第一個版本。你不需要.NET 3.5來使用這個類。 – 2011-09-19 01:27:12