我有一个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>
答案 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)
{
}
}