0

我有一个使用签名板 ( https://github.com/xamarin/SignaturePad )的 Xamarin 表单页面。我正在尝试捕获整个视图的屏幕截图。它也应该包括签名。

但是,使用以下代码我注意到签名没有显示出来。

捕获包括签名在内的整个页面的最佳方式是什么?(不仅仅是签名)

public class ScreenshotService : IScreenshotService
{
    public async Task<byte[]> CaptureAsync()
    {
    var rtb = new RenderTargetBitmap();
    await rtb.RenderAsync(Window.Current.Content);

    var pixelBuffer = await rtb.GetPixelsAsync();
    var pixels = pixelBuffer.ToArray();

    // Useful for rendering in the correct DPI
    var displayInformation = DisplayInformation.GetForCurrentView();

    var stream = new InMemoryRandomAccessStream();
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
    encoder.SetPixelData(BitmapPixelFormat.Bgra8,
    BitmapAlphaMode.Premultiplied,
    (uint)rtb.PixelWidth,
    (uint)rtb.PixelHeight,
    displayInformation.RawDpiX,
    displayInformation.RawDpiY,
    pixels);

    await encoder.FlushAsync();
    stream.Seek(0);

    var readStram = stream.AsStreamForRead();
    var bytes = new byte[readStram.Length];
    readStram.Read(bytes, 0, bytes.Length);

    return bytes;
}
}
4

2 回答 2

2

根据RenderTargetBitmap类的“XAML 视觉效果和 RenderTargetBitmap 捕获能力”:

无法捕获的内容将在捕获的图像中显示为空白,但同一视觉树中的其他内容仍然可以捕获并呈现(无法捕获的内容的存在不会使整个捕获无效) XAML 组合)。

因此,可能是 InkCanvas 的内容不可捕获。但是,您可以使用Win2D. 有关更多信息,您可以参考以下代码。

public async Task<Stream> CaptureAsync(Stream Tem)
{
    var rtb = new RenderTargetBitmap();
    await rtb.RenderAsync(Window.Current.Content);

    var pixelBuffer = await rtb.GetPixelsAsync();
    var pixels = pixelBuffer.ToArray();

    var displayInformation = DisplayInformation.GetForCurrentView();
    var stream = new InMemoryRandomAccessStream();
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
    encoder.SetPixelData(BitmapPixelFormat.Bgra8,
    BitmapAlphaMode.Premultiplied,
    (uint)rtb.PixelWidth,
    (uint)rtb.PixelHeight,
    displayInformation.RawDpiX,
    displayInformation.RawDpiY,
    pixels);
    await encoder.FlushAsync();
    stream.Seek(0);
    var readStram = stream.AsStreamForRead();

    var pagebitmap = await GetSoftwareBitmap(readStram);
    var softwareBitmap = await GetSoftwareBitmap(Tem);

    CanvasDevice device = CanvasDevice.GetSharedDevice();
    CanvasRenderTarget renderTarget = new CanvasRenderTarget(device, rtb.PixelWidth, rtb.PixelHeight, 96);

    using (var ds = renderTarget.CreateDrawingSession())
    {
        ds.Clear(Colors.White);
        var page = CanvasBitmap.CreateFromSoftwareBitmap(device, pagebitmap);
        var image = CanvasBitmap.CreateFromSoftwareBitmap(device, softwareBitmap);
        ds.DrawImage(page);
        ds.DrawImage(image);
    }

    InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
    await renderTarget.SaveAsync(randomAccessStream, CanvasBitmapFileFormat.Jpeg, 1f);
    return randomAccessStream.AsStream();
}

 private async Task<SoftwareBitmap> GetSoftwareBitmap(Stream data)
 {
   BitmapDecoder pagedecoder = await BitmapDecoder.CreateAsync(data.AsRandomAccessStream());
   return await pagedecoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
 }

IScreenshotServicecs 接口

public interface IScreenshotServicecs
{
    Task<Stream> CaptureAsync(Stream stream);
}

用法

var stream = await SignatureView.GetImageStreamAsync(SignaturePad.Forms.SignatureImageFormat.Png);
var data = await DependencyService.Get<IScreenshotServicecs>().CaptureAsync(stream);
MyImage.Source = ImageSource.FromStream(() => data);
于 2017-11-14T04:49:03.990 回答
1

这是我的最终实现,包括转换为字节数组。

    public async Task<byte[]> CaptureAsync(Stream signatureStream)
    {
        var rtb = new RenderTargetBitmap();
        await rtb.RenderAsync(Window.Current.Content);

        var pixelBuffer = await rtb.GetPixelsAsync();
        var pixels = pixelBuffer.ToArray();

        var displayInformation = DisplayInformation.GetForCurrentView();
        var stream = new InMemoryRandomAccessStream();
        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
        encoder.SetPixelData(BitmapPixelFormat.Bgra8,
        BitmapAlphaMode.Premultiplied,
        (uint)rtb.PixelWidth,
        (uint)rtb.PixelHeight,
        displayInformation.RawDpiX,
        displayInformation.RawDpiY,
        pixels);
        await encoder.FlushAsync();
        stream.Seek(0);
        var readStram = stream.AsStreamForRead();

        var pagebitmap = await GetSoftwareBitmap(readStram);
        var softwareBitmap = await GetSoftwareBitmap(signatureStream);

        CanvasDevice device = CanvasDevice.GetSharedDevice();
        CanvasRenderTarget renderTarget = new CanvasRenderTarget(device, rtb.PixelWidth, rtb.PixelHeight, 96);

        using (var ds = renderTarget.CreateDrawingSession())
        {
            ds.Clear(Colors.White);
            var page = CanvasBitmap.CreateFromSoftwareBitmap(device, pagebitmap);
            var image = CanvasBitmap.CreateFromSoftwareBitmap(device, softwareBitmap);
            ds.DrawImage(page);
            ds.DrawImage(image, 50, 55);
        }

        InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
        await renderTarget.SaveAsync(randomAccessStream, CanvasBitmapFileFormat.Jpeg, 1f);

        var fileBytes = new byte[randomAccessStream.Size];
        using (var reader = new DataReader(randomAccessStream))
        {
            await reader.LoadAsync((uint)randomAccessStream.Size);
            reader.ReadBytes(fileBytes);
        }

        return fileBytes;
    }
于 2017-11-17T15:02:49.970 回答