我在我的应用中打开了一个图像,并使用以下代码获取图像的像素数据。
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阵列?如果我有图像的二维数组,我知道怎么做。
现在,我脑子里有一个想法。
这是一个很好的解决方案吗? 如果有更好的解决方案,请帮助我。
答案 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;
}
}
}
}