从特定区域裁剪 inkCanvas 绘图,Windows 通用应用

本文关键字:Windows 应用 绘图 inkCanvas 区域 裁剪 | 更新日期: 2023-09-27 17:58:20

我已经设法从 inkCanvas 上的绘图中获得了我需要裁剪的区域的x,y,height,width。 但我无法找到正确的解决方案来裁剪该区域并将其另存为图像。

编辑:这是整个故事:一年前,我为Windows Phone 8.1 Silverlight开发了一个绘图应用程序。使用此示例

http://bsubramanyamraju.blogspot.com/2014/03/windows-phone-ink-supportsignature.html

现在我正在尝试为寡妇提供一些不同功能的相同功能。我正在从头开始开发它,因为现在 win10 中提供了墨迹书写,而且我不能使用旧代码,因为它包含仅适用于 Silverlight 应用程序的 InkPresenter。

这是我上次用于裁剪该区域的代码(这不是我自己的代码,我在网上得到了它(

static WriteableBitmap CropImage(WriteableBitmap source,
                                                           int xOffset, int yOffset,
                                                           int width, int height)
    {
        // Get the width of the source image
        var sourceWidth = source.PixelWidth;
        // Get the resultant image as WriteableBitmap with specified size
        var result = new WriteableBitmap(width, height);
        // Create the array of bytes
        for (var x = 0; x <= height - 1; x++)
        {
            var sourceIndex = xOffset + (yOffset + x) * sourceWidth;
            var destinationIndex = x * width;
            Array.Copy(source.Pixels, sourceIndex, result.Pixels, destinationIndex, width);
        }
        return result;
    }

但现在它说

'WriteableBitmap' does not contain a definition for 'Pixels' 

source.Pixelssource.Pixels,我不知道如何解决它。

我发布了这个问题,希望必须有一种直接的方法来裁剪 InkCanvas 区域,因为它现在是 win10 的一部分。

编辑 2@Jay我在参数中传递的宽度和高度是我想要裁剪的区域相对于 x 和 y 的宽度和高度。我尝试调试以检查decoder.PixelWidthheight的值。它始终与我在参数中提供的宽度和高度相同。

所以现在如果 xoffset =185yoffset=100以及参数中的heightwidth5060的。decoder.PixelWidthdecoder.PixelHeight也将与参数相同。这就是 if 条件的样子

if (pixelWidth > decoder.PixelWidth - xOffset || pixelHeight > decoder.PixelHeight - yOffset)

if (60> 60 - 185 || 50> 50- 100)

if (60> -125 || 50> -50)

因此,此条件始终为真。 我哪里出错了?

希望我在这个编辑中没有打错字。

从特定区域裁剪 inkCanvas 绘图,Windows 通用应用

如您所知,UWP 中的 InkCanvas 与 Windows Phone 8.1 Silverlight 中的不同。有关如何在 UWP 中使用InkCanvas,请参阅 UWP 应用中的笔和触笔交互。

要从特定区域裁剪 inkCanvas 绘图,我们可以先使用 IInkStrokeContainer.SaveAsync 方法存储墨迹笔划,然后使用 BitmapTransform 类裁剪图像。例如:

public static async System.Threading.Tasks.Task<WriteableBitmap> CropImageAsync(InkCanvas source, int xOffset, int yOffset, int pixelWidth, int pixelHeight)
{
    if (source.InkPresenter.StrokeContainer.GetStrokes().Count > 0)
    {
        using (var memStream = new InMemoryRandomAccessStream())
        {
            await source.InkPresenter.StrokeContainer.SaveAsync(memStream);
            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(memStream);
            //pixelWidth and pixelHeight must less than the available pixel width and height
            if (pixelWidth > decoder.PixelWidth - xOffset || pixelHeight > decoder.PixelHeight - yOffset)
            {
                return null;
            }
            BitmapTransform transform = new BitmapTransform();
            BitmapBounds bounds = new BitmapBounds();
            bounds.X = (uint)xOffset;
            bounds.Y = (uint)yOffset;
            bounds.Width = (uint)pixelWidth;
            bounds.Height = (uint)pixelHeight;
            transform.Bounds = bounds;
            // Get the cropped pixels within the bounds of transform.
            PixelDataProvider pix = await decoder.GetPixelDataAsync(
                BitmapPixelFormat.Bgra8, // WriteableBitmap uses BGRA format
                BitmapAlphaMode.Straight,
                transform,
                ExifOrientationMode.IgnoreExifOrientation,
                ColorManagementMode.DoNotColorManage);
            byte[] pixels = pix.DetachPixelData();
            var cropBmp = new WriteableBitmap(pixelWidth, pixelHeight);
            // Stream the bytes into a WriteableBitmap
            using (Stream stream = cropBmp.PixelBuffer.AsStream())
            {
                await stream.WriteAsync(pixels, 0, pixels.Length);
            }
            return cropBmp;
        }
    }
    else
    {
        return null;
    }
}