在UWP App中将掩码应用于位图图像

时间:2016-03-26 12:04:16

标签: c# image-processing bitmap win-universal-app

我在我的应用中打开了一个图像,并使用以下代码获取图像的像素数据。

  using (IRandomAccessStream fileStreams = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
            {
                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStreams);
                BitmapTransform transform = new BitmapTransform()
                {
                    ScaledWidth = Convert.ToUInt32(bitmapImage.PixelWidth),
                    ScaledHeight = Convert.ToUInt32(bitmapImage.PixelHeight)
                };
                PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
                    BitmapPixelFormat.Bgra8,
                    BitmapAlphaMode.Straight,
                    transform,
                    ExifOrientationMode.IgnoreExifOrientation,
                    ColorManagementMode.DoNotColorManage
               );

                byte[] sourcePixels = pixelData.DetachPixelData();                
            }

这里我有一个包含图像所有像素的数组。此数组中的像素总数为(宽*高* 4)。在分析了这个数组之后,我才知道索引号0,1,2和3包含第一个像素的红色,绿色和alpha值,索引号4,5,6和7包含红色,绿色,蓝色和alpha图像的第二像素的值等。

现在我想将3x3滤镜应用于此图像,我该如何使用这个1-D阵列?如果我有图像的二维数组,我知道怎么做。

现在,我脑子里有一个想法。

  1. 将红色像素存储在一个2D阵列中,将绿色存储在其他2D阵列中
  2. 在每个2d阵列上应用过滤器。
  3. 将所有这些组合在一起再制作1-D数组并返回结果。
  4. 这是一个很好的解决方案吗? 如果有更好的解决方案,请帮助我。

1 个答案:

答案 0 :(得分:1)

如果要在UWP中屏蔽Bitmapimage,则需要对图像的原始像素数据使用软件位图。 首先,您需要分离图像和蒙版数据,并将其转换为BGRA格式的字节数组。 然后,您需要使用不安全的代码来访问该位置。

创建一个界面。

[ComImport] [Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] unsafe interface IMemoryBufferByteAccess { void GetBuffer(out byte* buffer, out uint capacity); }

使用以下代码段更改/编辑软件位图像素。

创建软件位图。

softwareBitmap = new SoftwareBitmap(BitmapPixelFormat.Bgra8, 100, 100, BitmapAlphaMode.Premultiplied);

using (BitmapBuffer buffer = softwareBitmap.LockBuffer(BitmapBufferAccessMode.Write))
{
    using (var reference = buffer.CreateReference())
    {
        byte* dataInBytes;
        uint capacity;
        ((IMemoryBufferByteAccess)reference).GetBuffer(out dataInBytes, out capacity);

        // Fill-in the BGRA plane
        BitmapPlaneDescription bufferLayout = buffer.GetPlaneDescription(0);
        for (int i = 0; i < bufferLayout.Height; i++)
        {
            for (int j = 0; j < bufferLayout.Width; j++)
            {

                byte value = (byte)((float)j / bufferLayout.Width * 255);
                dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 0] = value;
                dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 1] = value;
                dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 2] = value;
                dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 3] = (byte)255;
            }
        }
    }
}