如何裁剪和保存 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),所以Canvas 需要 为 800x800 像素。
编辑: 或者有什么方法可以 Clip
a canvas 而不影响其子元素的 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>
保存前不要剪辑:保存时剪辑。
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)
{
}
}
我有一个 ItemsControl
,其中包含一个 Canvas
(800x800px) 和一个 Rectangles
在特定坐标处的集合。
我可以将 ItemsControl
保存为 RenderTargetBitmap
这很好,但我需要在指定的 X、Y、W、H 处裁剪它,然后保存它,我似乎无法弄清楚如何要做。
我试过使用 Canvas.Clip
剪裁 Canvas
,然后保存它,但这会使我的 Rectangles
移出它们指定的坐标(CollageX、CollageY),所以Canvas 需要 为 800x800 像素。
编辑: 或者有什么方法可以 Clip
a canvas 而不影响其子元素的 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>
保存前不要剪辑:保存时剪辑。
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)
{
}
}