Как обрезать и сохранить UWP RenderTargetBitmap - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть ItemsControl, который содержит Canvas (800x800px) и набор Rectangles в определенных координатах.Я могу сохранить ItemsControl как RenderTargetBitmap, и это нормально, но мне нужно обрезать его с указанными значениями X, Y, W, H, а затем сохранить его, что я не могу понять, как это сделать.

Я попытался обрезать Canvas, используя Canvas.Clip, а затем сохранить его, но это заставило мой Rectangles выйти за пределы указанных координат (CollageX, CollageY), поэтому для Canvas нужны будет 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 голосов
/ 10 февраля 2019

хорошо, так что я не уверен, поможет ли это, но люди, ищущие, как обрезать изображение, наверняка оценят этот ответ как действительно чистый и быстрый.

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

            }
        }
0 голосов
/ 09 февраля 2019

Не обрезайте его перед сохранением: обрезайте при сохранении.

BitmapEncoder имеет свойство BitmapTransform , которое можно использовать для управления его кодированием, включая масштабирование,переворачивание, вращение и отсечение .

...