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