Xamarin表单UWP Capture截图包括签名板

时间:2017-11-10 15:50:56

标签: xamarin xamarin.forms uwp signaturepad

我有一个使用签名板(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;
}
}

2 个答案:

答案 0 :(得分:2)

根据RenderTargetBitmap类的“XAML visuals和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);

答案 1 :(得分: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;
    }