如何裁剪和保存RenderTargetBitmap UWP

时间:2019-02-07 13:34:37

标签: c# xaml uwp itemscontrol rendertargetbitmap

我有一个ItemsControl,其中包含Canvas(800x800px)和在特定坐标处的Rectangles集合。 我可以将ItemsControl保存为RenderTargetBitmap,这很好,但是我需要将其裁剪为指定的X,Y,W,H,然后将其保存,但似乎无法弄清楚要做。

我尝试使用Canvas裁剪Canvas.Clip,然后再保存,但这使我的Rectangles移出了它们的指定坐标(CollageX,CollageY),因此Canvas < strong>需要为800x800px。

编辑:或者是否有某种方法可以Clip在不影响其子元素的X和Y位置的情况下使用画布?

这就是我当前的代码。

C#

private async void SaveDesignBtn_Tapped(object sender, TappedRoutedEventArgs e)
    {

    //Images
    RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
    await renderTargetBitmap.RenderAsync(MaskArea, (int)PrintW, (int)PrintH);

    var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
    var pixels = pixelBuffer.ToArray();
    var displayInformation = DisplayInformation.GetForCurrentView();
    var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("Canvas1" + ".png", CreationCollisionOption.ReplaceExisting);
    using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
        {
            var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
            encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, displayInformation.RawDpiX, displayInformation.RawDpiY, pixels);
            await encoder.FlushAsync();
        }
    }

XAML

    <ItemsControl Name="MaskArea" ItemsSource="{Binding Path=CollageGrid}" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,0,0,0" Width="800" Height="800">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas x:Name="CollageArea" 
                        Background="Transparent" 
                        Width="800" 
                        Height="800"                
                        HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,0,0,0">
                </Canvas>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate x:DataType="local:CollageGrid">
                <Rectangle Name="MaskBounds" Width="{Binding CollageW}" Height="{Binding CollageH}" AllowDrop="True" CanDrag="True"
                            Drop="Mask_Drop"  
                            DragOver="Mask_DragOver"
                            ManipulationMode="All" Stroke="Black" StrokeThickness="2" DragEnter="Mask_DragEnter" DragLeave="Mask_DragLeave" Tapped="Tap_Collage"
                            RenderTransformOrigin="0.5, 0.5"
                            Canvas.Left="{Binding CollageX}" Canvas.Top="{Binding CollageY}" Fill="Transparent">
                        <Rectangle.RenderTransform>
                            <TranslateTransform X="{Binding CollageX}" Y="{Binding CollageY}"/>
                        </Rectangle.RenderTransform>
                </Rectangle>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

2 个答案:

答案 0 :(得分:1)

在保存之前不对其进行剪辑:在保存时对其进行剪辑。

BitmapEncoder具有BitmapTransform属性,可用于控制其编码方式,包括缩放,翻转,旋转和剪切

答案 1 :(得分:0)

好吧,所以我不确定这是否有帮助,但是寻找如何裁剪图像的人们肯定会喜欢这个答案,因为它确实干净快捷。

private async void GetCanvasBitmapRegion(Rect RegionToCopy)
        {
            try
            {
                CanvasDevice Cdevice = CanvasDevice.GetSharedDevice();



                var croppedwidth = (int)RegionToCopy.Width;
                var croppedheight = (int)RegionToCopy.Height;

                //create a new empty image that has the same size as the desired crop region
                var softwareBitmap = new SoftwareBitmap(BitmapPixelFormat.Bgra8, croppedwidth, croppedheight,
                    BitmapAlphaMode.Premultiplied);

                //based on this empty software bitmap we create a new CanvasBitmap
                var croppedimage = CanvasBitmap.CreateFromSoftwareBitmap(Cdevice, softwareBitmap);

                // this is the image we want to crop from, CanvasBitmap has lots of static initializers that like CanvasBitmap.LoadAsync 
                //or CanvasBitmap.CreateFromBytes
                CanvasBitmap initialimage = _image;

                if (initialimage != null)
                {

                    //this function does the cropped region copy.
                    croppedimage.CopyPixelsFromBitmap(_image, 0, 0, (int)RegionToCopy.Left, (int)RegionToCopy.Top, (int)RegionToCopy.Width, (int)RegionToCopy.Height);


                   //you can now do whatever you like with croppedimage, including using its .SaveAsync or replace the old one with it.
                }

            }
            catch (Exception Ex)
            {

            }
        }