繁体   English   中英

如何裁剪和保存 RenderTargetBitmap UWP

[英]How to crop and save a RenderTargetBitmap UWP

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

我试过使用Canvas.Clip裁剪Canvas ,然后保存它,但这会使我的Rectangles移出它们指定的坐标(CollageX、CollageY),因此画布需要为 800x800px。

编辑:或者有什么方法可以在不影响其子元素的 X 和 Y 位置的情况下Clip画布?

这是我当前的代码的样子。

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>

不要在保存之前剪辑它:保存时剪辑它。

BitmapEncoder 有一个BitmapTransform属性,您可以使用它来控制它的编码方式,包括缩放、翻转、旋转和剪辑

好的,所以我不确定这是否有帮助,但是查找如何裁剪图像的人肯定会喜欢这个答案,因为它非常干净和快速。

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)
            {

            }
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM