如何从CapturedPhoto UWP获取子图像

时间:2018-04-18 09:59:46

标签: c# uwp

我想保存使用网络摄像头拍摄的图像的一部分(使用Windows.Media.Capture)。

这是我到目前为止所得到的:

 [...]
 MediaCapture mediaCapture = new MediaCapture();
 await mediaCapture.InitializeAsync();
 await mediaCapture.StartPreviewAsync();
 public async void takePhoto(){
    var lowLagCapture = await mediaCapture.PrepareLowLagPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Bgra8));
    var capturedPhoto = await lowLagCapture.CaptureAsync();
    await lowLagCapture.FinishAsync();
    await CapturePhotoWithOrientationAsync();
 }

 private async Task CapturePhotoWithOrientationAsync() {
        var captureStream = new InMemoryRandomAccessStream();

        try {
            await mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), captureStream);
        } catch (Exception ex) {
            Debug.WriteLine("Exception when taking a photo: {0}", ex.ToString());
            return;
        }

        var decoder = await BitmapDecoder.CreateAsync(captureStream);
        var file = await storageFolder.CreateFileAsync("test.jpeg", CreationCollisionOption.ReplaceExisting);

        using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite)) {
            var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);
            var photoOrientation = CameraRotationHelper.ConvertSimpleOrientationToPhotoOrientation(Windows.Devices.Sensors.SimpleOrientation.Rotated270DegreesCounterclockwise);
            var properties = new BitmapPropertySet {
                { "System.Photo.Orientation", new BitmapTypedValue(photoOrientation, PropertyType.UInt16) } };
            await encoder.BitmapProperties.SetPropertiesAsync(properties);
            await encoder.FlushAsync();
        }
    }
[...]

这样我就可以保存整个图像。但是,我怎样才能保存图像的一部分呢?

1 个答案:

答案 0 :(得分:0)

  

但我怎样才能保存图像的一部分?

使用起点和大小,您可以定义裁剪边界,然后创建BitmapTransform,通过此变换,您可以通过GetPixelDataAsync()方法获得裁剪后的图像像素。 BitmapEncoder可以SetPixelData。有关具体方法请参考How to crop bitmap in a Windows Store app (C#)示例和this tutorial

例如,根据您的代码段:

//Inside CapturePhotoWithOrientationAsync method
...
Point startPoint = new Point(0, 0);
Size corpSize = new Size(250, 250);
// Convert start point and size to integer. 
uint startPointX = (uint)Math.Floor(startPoint.X);
uint startPointY = (uint)Math.Floor(startPoint.Y);
uint height = (uint)Math.Floor(corpSize.Height);
uint width = (uint)Math.Floor(corpSize.Width);
// Refine the start point and the size.  
if (startPointX + width > decoder.PixelWidth)
{
    startPointX = decoder.PixelWidth - width;
}

if (startPointY + height > decoder.PixelHeight)
{
    startPointY = decoder.PixelHeight - height;
}

// Create cropping BitmapTransform to define the bounds. 
BitmapTransform transform = new BitmapTransform();
BitmapBounds bounds = new BitmapBounds();
bounds.X = startPointX;
bounds.Y = startPointY;
bounds.Height = height;
bounds.Width = width;
transform.Bounds = bounds; 

// Get the cropped pixels within the the bounds of transform. 
PixelDataProvider pix = await decoder.GetPixelDataAsync(
    BitmapPixelFormat.Bgra8,
    BitmapAlphaMode.Straight,
    transform,
    ExifOrientationMode.IgnoreExifOrientation,
    ColorManagementMode.ColorManageToSRgb);
byte[] pixels = pix.DetachPixelData(); 

StorageFolder storageFolder = KnownFolders.PicturesLibrary;
var file = await storageFolder.CreateFileAsync("test.jpeg", CreationCollisionOption.ReplaceExisting);
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{    
    BitmapEncoder encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);
    // Set the pixel data to the cropped image. 
    encoder.SetPixelData(
        BitmapPixelFormat.Bgra8,
        BitmapAlphaMode.Straight,
        width,
        height,
        decoder.DpiX,
        decoder.DpiY,
        pixels); 

    // Flush the data to file. 
    await encoder.FlushAsync();
}