如何在UWP应用程序中裁剪位图?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在UWP应用程序中裁剪位图?相关的知识,希望对你有一定的参考价值。

有许多类似的问题,但它们似乎都没有回答我的问题。

我正在开发一个UWP应用程序(使用Syncfusion),它可以生成一些PDF。对于这个PDF,我需要获得一些Syncfusion.Pdf.Graphics.PdfBitmap,但在此之前,我需要稍微裁剪它。

这就是我正在做的,我得到我的图并将其转换为PdfBitmap:

 var diagramBitmap = new PdfBitmap(diagram);

然后我需要通过以下方式将其绘制成PDF:

 document.Pages[0].Graphics.DrawImage(diagramBitmap, x, y, width, height);

问题是,我找到的解决方案都没有在UWP中轻松地在绘制之前裁剪PdfBitmap。我解决了这个问题,没有裁剪图表,它正在工作,但裁剪它是更好,更好的解决方案。

感谢您的帮助或建议!

答案

此代码从现有的SoftwareBitmap创建一个新的裁剪的SoftwareBitmap。如果图像已经在内存中,则很有用。

    async public static Task<SoftwareBitmap> GetCroppedBitmapAsync(SoftwareBitmap softwareBitmap, 
            uint startPointX, uint startPointY, uint width, uint height)
    {            
        using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
        {
            BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream);

            encoder.SetSoftwareBitmap(softwareBitmap);

            encoder.BitmapTransform.Bounds = new BitmapBounds()
            {
                X = startPointX,
                Y = startPointY,
                Height = height,
                Width = width
            };

            await encoder.FlushAsync();

            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);

            return await decoder.GetSoftwareBitmapAsync(softwareBitmap.BitmapPixelFormat, softwareBitmap.BitmapAlphaMode);
        }
    }
另一答案

问题是,我找到的解决方案都没有在UWP中轻松地在绘制之前裁剪PdfBitmap。我解决了这个问题,没有裁剪图表,它正在工作,但裁剪它是更好,更好的解决方案。

您可以在创建PdfBitmap之前裁剪它。有一个很好的示例项目用于在UWP中裁剪​​图像。请参考UWP-ImageCropper。您可以像下面一样修改核心功能,使其满足您的要求:

/// <param name="originalImgFile">Image File that you want to crop</param>
/// <param name="startPoint">From which point you want to crop</param>
/// <param name="corpSize">The crop size of the image</param>
/// <param name="scale">The scale of cropped image</param>
async public static Task<Stream> GetCroppedBitmapAsync(StorageFile originalImgFile, System.Drawing.Point startPoint, System.Drawing.Size corpSize, double scale)
{
    if (double.IsNaN(scale) || double.IsInfinity(scale))
    {
        scale = 1;
    }


    // Convert start point and size to integer. 
    uint startPointX = (uint)Math.Floor(startPoint.X * scale);
    uint startPointY = (uint)Math.Floor(startPoint.Y * scale);
    uint height = (uint)Math.Floor(corpSize.Height * scale);
    uint width = (uint)Math.Floor(corpSize.Width * scale);


    using (IRandomAccessStream stream = await originalImgFile.OpenReadAsync())
    {


        // Create a decoder from the stream. With the decoder, we can get  
        // the properties of the image. 
        BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);

        // The scaledSize of original image. 
        uint scaledWidth = (uint)Math.Floor(decoder.PixelWidth * scale);
        uint scaledHeight = (uint)Math.Floor(decoder.PixelHeight * scale);



        // Refine the start point and the size.  
        if (startPointX + width > scaledWidth)
        {
            startPointX = scaledWidth - width;
        }

        if (startPointY + height > scaledHeight)
        {
            startPointY = scaledHeight - height;
        }


        // Create cropping BitmapTransform and define the bounds. 
        BitmapTransform transform = new BitmapTransform();
        BitmapBounds bounds = new BitmapBounds();
        bounds.X = startPointX;
        bounds.Y = startPointY;
        bounds.Height = height;
        bounds.Width = width;
        transform.Bounds = bounds;


        transform.ScaledWidth = 100;
        transform.ScaledHeight = 100;

        // Get the cropped pixels within the bounds of transform. 
        PixelDataProvider pix = await decoder.GetPixelDataAsync(
            BitmapPixelFormat.Bgra8,
            BitmapAlphaMode.Straight,
            transform,
            ExifOrientationMode.IgnoreExifOrientation,
            ColorManagementMode.ColorManageToSRgb);
        byte[] pixels = pix.DetachPixelData();


        // Stream the bytes into a WriteableBitmap 
        WriteableBitmap cropBmp = new WriteableBitmap((int)width, (int)height);
        Stream pixStream = cropBmp.PixelBuffer.AsStream();
        pixStream.Write(pixels, 0, (int)(width * height * 4));


        return pixStream;
    }
}

然后你可以用它来制作你的PdfBitmap

var imageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/image03.jpg"));
Stream  bitmap = await GetCroppedBitmapAsync(imageFile, new System.Drawing.Point(100, 100), new System.Drawing.Size(100, 100), 1);
PdfBitmap image = new PdfBitmap(bitmap);

以上是关于如何在UWP应用程序中裁剪位图?的主要内容,如果未能解决你的问题,请参考以下文章

如何在两个片段之间传递位图? (我正在使用 Android 导航组件)

如何使用firemonkey在选定区域裁剪位图?

如何以最少的内存使用裁剪位图?

如何在Android中从位图中裁剪圆形区域

如何裁剪位图并获得图像的下 50%

使用 Path 对象裁剪位图