Подпись пользователя в универсальном приложении для Windows 8.1
Есть ли возможность подписать документ на мобильном устройстве с Windows 8.1? Что-то вроде холста, где пользователь сможет нарисовать свою подпись вручную или стилусом. Есть ли какой-либо элемент управления XAML для этой задачи или что-то еще?
1 ответ
Я боролся с этим большую часть дня. Кажется, что встроенный контроль рукописного ввода, который был доступен в Windows Phone 7 и 8.0, был извлечен для 8.1
Я использовал приемы из статьи, на которые указал Крис В., чтобы создать элемент управления, который можно добавить в XAML страницы и обрабатывать все остальное.
Волшебство заключается в методах WritableBitmap и PointerPressed и PointerMoved.
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
namespace ProofOfConcept.App.Controls
{
public class SignatureCaptureControl : Canvas
{
private WriteableBitmap _writeableBitmap;
private Point _currentPoint;
private Point _oldPoint;
public SignatureCaptureControl()
{
_writeableBitmap = new WriteableBitmap(300, 130);
PointerPressed += SignatureCaptureControl_PointerPressed;
PointerMoved += SignatureCaptureControl_PointerMoved;
}
private void SignatureCaptureControl_PointerPressed(object sender, PointerRoutedEventArgs e)
{
_currentPoint = e.GetCurrentPoint(this).Position;
_oldPoint = _currentPoint;
}
void SignatureCaptureControl_PointerMoved(object sender, PointerRoutedEventArgs e)
{
_currentPoint = e.GetCurrentPoint(this).Position;
_writeableBitmap.DrawLine((int)_currentPoint.X, (int)_currentPoint.Y, (int)_oldPoint.X, (int)_oldPoint.Y, PenColor);
this.InvalidateArrange();
_oldPoint = _currentPoint;
}
public void ClearSignature()
{
_writeableBitmap.Clear();
}
}
}
Использование следующего Элемент управления отобразит белое поле 300x130, которое будет рисовать линии при перетаскивании на него пальца или стилуса.
<Border Background="White">
<controls:SignatureCaptureControl Height="130" Width="300"/>
</Border>
Чтобы получить изображение, мы должны извлечь данные пикселей из WritableBitmap, а затем закодировать их как Bitmap/Gif/Jpeg/Png/ и т.д.
public Task<byte[]> ReadAsPngImageAsync()
{
return ReadImageFromWritableBitmapAsync(_writeableBitmap, Windows.Graphics.Imaging.BitmapEncoder.PngEncoderId);
}
internal static async Task<byte[]> ReadImageFromWritableBitmapAsync(Windows.UI.Xaml.Media.Imaging.WriteableBitmap writeableBitmap, Guid encoderId)
{
var rawPixels = await ConvertBitmapToByteArrayAsync(writeableBitmap);
var encodedPixels = await EncodePixels(rawPixels, encoderId, (uint)writeableBitmap.PixelWidth, (uint)writeableBitmap.PixelHeight);
return encodedPixels;
}
private static async Task<byte[]> ConvertBitmapToByteArrayAsync(Windows.UI.Xaml.Media.Imaging.WriteableBitmap bitmap)
{
using (var stream = bitmap.PixelBuffer.AsStream())
{
var pixels = new byte[(uint)stream.Length];
await stream.ReadAsync(pixels, 0, pixels.Length);
return pixels;
}
}
private static async Task<byte[]> EncodePixels(byte[] signaturePixels, Guid encoderId, uint pixelWidth, uint pixelHeight)
{
using (var randomAccessStream = new Windows.Storage.Streams.InMemoryRandomAccessStream())
{
var encoder = await Windows.Graphics.Imaging.BitmapEncoder.CreateAsync(encoderId, randomAccessStream);
encoder.SetPixelData(Windows.Graphics.Imaging.BitmapPixelFormat.Bgra8, Windows.Graphics.Imaging.BitmapAlphaMode.Premultiplied,
pixelWidth, pixelHeight,
96, 96, signaturePixels);
await encoder.FlushAsync();
using (var stream = randomAccessStream.GetInputStreamAt(0))
{
var pixels = new byte[(uint)randomAccessStream.Size];
stream.AsStreamForRead().Read(pixels, 0, pixels.Length);
return pixels;
}
}
}
Теперь у нас есть байтовый массив, представляющий изображение в стандартной форме, мы можем просто сохранить данные в локальном хранилище или отправить их в службу.