如何从捕获的图像C#访问/编辑像素

时间:2016-04-29 22:47:11

标签: c# camera win-universal-app

我正在尝试将自己的自定义效果应用于图片,因此我需要能够访问图像的各个像素。使用MediaCapture我可以将CapturedPhoto.Frame作为流或softwarebitmap获取,但我无法找到如何编辑它们。

//initialize mediacapture with default camera
var mediaCapture = new MediaCapture();
await mediaCapture.InitializeAsync();

//create low lag capture and take photo
var lowLagCapture = await mediaCapture.PrepareLowLagPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Bgra8));
var capturedPhoto = await lowLagCapture.CaptureAsync();

capturedPhoto.Frame.AsStream()
capturedPhoto.Frame.SoftwareBitmap

1 个答案:

答案 0 :(得分:3)

要访问图像的像素,您可以使用SoftwareBitmap。要访问RGB颜色空间中的像素,您可以使用Bgra8颜色格式。要转换为Bgra8,请使用

var softwareBitmap = SoftwareBitmap.Convert(capturedPhoto.Frame.SoftwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);

要访问图像的字节,您需要通过在命名空间中添加以下代码来初始化IMemoryBufferByteAccess COM接口

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

接下来,您需要设置不安全的编译器标志。右键单击项目 - >属性 - >构建 - >检查允许不安全的代码。

现在您可以直接访问/编辑像素,如下所示。

public unsafe void editSoftwarebitmap(SoftwareBitmap softwareBitmap)
{
    //create buffer
    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++)
                {
                    //get offset of the current pixel
                    var pixelStart = bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j;

                    //get gradient value to set for blue green and red
                    byte value = (byte)((float)j / bufferLayout.Width * 255);
                    dataInBytes[pixelStart + 0] = value; //Blue
                    dataInBytes[pixelStart + 1] = value; //Green
                    dataInBytes[pixelStart + 2] = value; //Red
                    dataInBytes[pixelStart + 3] = (byte)255; //Alpha
                }
            }
        }
    }
}

有关更多文档,请参阅Imaging How-To