【问题标题】:How to draw a rectangle using WriteableBitmap?如何使用 WriteableBitmap 绘制一个矩形?
【发布时间】:2019-10-06 17:20:14
【问题描述】:

我创建了一个 WPF 项目,其中仅包含一个 Image 控件。

<Image 
  x:Name='img'
  Width='256'
  Height='256'
  MouseDown='img_MouseDown' />

我的目标是点击图片并在点击发生的特定位置绘制一个白色的10像素边正方形

一开始我尝试绘制 1 像素大小的正方形并按预期工作。

代码如下:

 public partial class MainWindow : Window
    {
        WriteableBitmap wb;

        public MainWindow()
        {
            InitializeComponent();
            wb = new WriteableBitmap(256, 256, 96d, 96d, PixelFormats.Bgr24, null);
            img.Source = wb;
        }

        private void img_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Point p = e.GetPosition(img);

            Int32Rect rect = new Int32Rect((int)p.X, (int)p.Y, 1, 1);
            int stride = wb.PixelWidth * wb.Format.BitsPerPixel / 8;
            byte[] buffer = { 255, 255, 255 };
            wb.WritePixels(rect, buffer, stride, 0);
        }
    }

现在我想绘制一个 10 像素大小的正方形,我正在初始化 rect,宽度和高度为 10 像素,

Int32Rect rect = new Int32Rect((int)p.X, (int)p.Y, 10, 10);

,但是WritePixels() 抛出一个异常,提示“缓冲区大小不足。”出于绝望,我将缓冲区更改为 10 大小,但仍然出现相同的错误。

这里有什么问题?

【问题讨论】:

  • buffer 数组必须代表像素数据。您只提供一个像素,但该数组需要有 10 x 10 像素 x 3 个通道 = 300 个元素。
  • 好吧,我创建了一个 300 字节的缓冲区,但我仍然收到此错误@dymanoid!
  • 尝试使用 PixelFormats.Bgr32 和 4 字节/像素,我遇到了 Bgr24 的一些问题,在移动到 32 后消失了。

标签: c# wpf bitmap writeablebitmap


【解决方案1】:

stride 参数是输入缓冲区的参数,即此处的 3 x 10:

var width = 10;
var height = 10;
var stride = (width * wb.Format.BitsPerPixel + 7) / 8;
var rect = new Int32Rect((int)p.X, (int)p.Y, width, height);
var buffer = Enumerable.Range(0, stride * height).Select(i => (byte)255).ToArray();
wb.WritePixels(rect, buffer, stride, 0);

【讨论】:

  • 好的,我正在计算整个位图的步幅,对吧?
  • 是的,你需要输入缓冲区的步幅。有关计算它的一般方法,请参阅答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-14
相关资源
最近更新 更多