【问题标题】:Why AccessViolationException occurs when accessing pixels in WriteableBitmap Image?为什么访问WriteableBitmap Image中的像素时会出现AccessViolationException?
【发布时间】:2016-03-01 15:58:44
【问题描述】:

我有一个从相机到 WPF 中图像的视频流。我试图在显示 WritableBitMap Image 之前逐个像素地访问它。作为测试,我试图将整个图像设置为白色或黑色。然而,在这两种情况下,我都会收到 AccessViolationException 错误。

我检查了其他帖子,似乎这个错误非常广泛,并不特定于我的情况。我似乎不知道为什么我没有得到这个工作。

那么在我的情况下,使用像素的最佳方法是什么?或者为什么这不起作用?任何帮助表示赞赏

     private async void UpdateMasterCameraPreview(IdsFrame frame)
    {
        if (masterImage != null)
            frame.Image.CopyTo(masterImage);
        else
            masterImage = frame.Image.ToWriteableBitmap();

        //BitmapImage temp = ConvertWriteableBitmapToBitmapImage(masterImage);
        WriteableBitmap temp = masterImage;

        // Here I get the exception, on every pixel access
        for (int y = 0; y < temp.PixelHeight; y++)
            for (int x = 0; x < temp.PixelWidth; x++)
                temp.SetPixel(x, y, 255);

        masterImage = temp;

        masterImage.Lock();
        masterImage.AddDirtyRect(new Int32Rect(0, 0, masterImage.PixelWidth, masterImage.PixelHeight));
        masterImage.Unlock();

        if (OnMasterFrameCaptured != null)
            OnMasterFrameCaptured(this, new CameraFrameCapturedArgs(CameraType.Master, masterImage));
    }

【问题讨论】:

  • 请同时包含临时变量声明。

标签: c# wpf writablebitmap


【解决方案1】:

你已经交换了X和Y,i代表高度,j代表宽度,那么你应该像这样调用SetPixel:

temp.SetPixel(j, i, 255);

在这种情况下,最好为变量使用有意义的名称,例如 X 和 Y。

【讨论】:

  • 你说得对,我也看到了函数原型。我交换了它们,但是,我仍然遇到同样的错误,AcessViolationException
  • SetPixel 不是 WriteableBitmap 的一部分,所以你有一个扩展或组件,发布函数的代码。
  • 但我们都只是使用它。为什么它不是 WritableBitmap 的一部分?
  • 我有一个这样的扩展,WriteableBitmapEx 也实现了它。看MSDN:msdn.microsoft.com/en-us/library/…
  • 我明白了。谢谢。我刚刚添加了整个东西,也许你能帮忙?
【解决方案2】:

我最终使用了this 帖子的答案。我现在可以编辑任何 WriteableBitmap 图像的原始像素数据,然后再将其发送到 WPF 中的图像控件。下面是我完全使用的,但在这里我只是在一个条件下将每一帧转换为某种透明度:

        public void ConvertImage(ref WriteableBitmap Wbmp)
    {
        int width = Wbmp.PixelWidth;
        int height = Wbmp.PixelHeight;
        int stride = Wbmp.BackBufferStride;
        int bytesPerPixel = (Wbmp.Format.BitsPerPixel + 7) / 8;

        unsafe
        {
            byte* pImgData = (byte*)Wbmp.BackBuffer;

            // set alpha to transparent for any pixel with red < 0x88 and invert others
            int cRowStart = 0;
            int cColStart = 0;
            for (int row = 0; row < height; row++)
            {
                cColStart = cRowStart;
                for (int col = 0; col < width; col++)
                {
                    byte* bPixel = pImgData + cColStart;
                    UInt32* iPixel = (UInt32*)bPixel;

                    if (bPixel[2 /* bgRa */] < 0x44)
                    {
                        // set to 50% transparent
                        bPixel[3 /* bgrA */] = 0x7f;
                    }
                    else
                    {
                        // invert but maintain alpha
                        *iPixel = *iPixel ^ 0x00ffffff;
                    }

                    cColStart += bytesPerPixel;
                }
                cRowStart += stride;
            }
        }
    }

而使用它的套路是这样的:

        masterImage.Lock();
        ConvertImage(ref masterImage);
        masterImage.AddDirtyRect(new Int32Rect(0, 0, masterImage.PixelWidth, masterImage.PixelHeight));
        masterImage.Unlock();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多