从特定区域裁剪inkCanvas绘图,Windows Universal App

时间:2016-07-22 19:50:48

标签: c# image-processing windows-10-universal inkcanvas

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

修改 这是整个故事: 我在一年前为windows phone 8.1 Silverlight开发了一个绘图应用程序。使用这个例子

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

现在我正在努力为寡妇普遍使用一些不同的功能做同样的事情。我正在从头开发它,因为现在在win10中可以使用墨水加上我不能使用旧代码,因为它包含InkPresenter,它仅适用于Silverlight应用程序。

这是我上次用于裁剪区域的代码(这不是我自己的代码,我在线获取)

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以及参数中的heightwidth5060decoder.PixelWidthdecoder.PixelHeight也与params相同。这就是if条件的样子

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

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

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

因此,这种情况总是正确的。我哪里错了?

希望我在这个编辑中没有做任何拼写错误。

1 个答案:

答案 0 :(得分:0)

如您所知,UWP中的InkCanvas与Windows Phone 8.1 Silverlight中的Pen and stylus interactions in UWP apps不同。有关如何在UWP中使用InkCanvas,请参阅IInkStrokeContainer.SaveAsync method

要从特定区域裁剪inkCanvas绘图,我们可以先使用BitmapTransform class存储墨迹笔划,然后使用{{3}}裁剪图像。例如:

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;
    }
}