• WPF实现签名拍照功能


    在这里插入图片描述

    ✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。
    🍎个人主页:Java Fans的博客
    🍊个人信条:不迁怒,不贰过。小知识,大智慧。
    💞当前专栏:WPF 案例及知识分享专栏
    ✨特色专栏:乐趣国学-心性养成之路
    🥭本文内容:WPF实现签名拍照功能
      当你使用WPF(Windows Presentation Foundation)技术编写一个签名拍照软件时,需要使用C#来处理界面和相机操作。以下是一个简单示例,展示如何创建一个WPF应用程序来实现这一功能。

    在这里插入图片描述

      首先,确保你已经安装了Visual Studio和.NET框架。然后,创建一个新的WPF应用程序项目,我们将称之为"SignatureCaptureApp"。

      在MainWindow.xaml中,创建界面布局,包括一个显示相机预览的区域、一个签名区域、一个按钮来拍照并保存签名。

    <Window x:Class="SignatureCaptureApp.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Signature Capture App" Height="400" Width="600">
        <Grid>
            <Image Name="CameraPreview" Width="400" Height="300" Stretch="UniformToFill" Margin="10"/>
            <InkCanvas Name="SignatureCanvas" Width="400" Height="100" Margin="10"/>
            <Button Content="拍照并保存签名" Click="CaptureSignature_Click" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,10"/>
        Grid>
    Window>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

      在MainWindow.xaml.cs中,添加相机和签名捕捉的逻辑。

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Ink;
    using System.Windows.Media.Imaging;
    using System.Windows.Media.Imaging;
    
    namespace SignatureCaptureApp
    {
        public partial class MainWindow : Window
        {
            private CameraCapture _cameraCapture;
    
            public MainWindow()
            {
                InitializeComponent();
                _cameraCapture = new CameraCapture(CameraPreview);
                _cameraCapture.InitializeCamera();
            }
    
            private void CaptureSignature_Click(object sender, RoutedEventArgs e)
            {
                // 拍照
                BitmapSource photo = _cameraCapture.CapturePhoto();
    
                // 保存签名
                if (SignatureCanvas.Strokes.Count > 0 && photo != null)
                {
                    SaveSignatureAndPhoto(SignatureCanvas.Strokes, photo);
                }
            }
    
            private void SaveSignatureAndPhoto(StrokeCollection strokes, BitmapSource photo)
            {
                try
                {
                    // 为签名创建一个独一无二的文件名
                    string signatureFileName = $"Signature_{DateTime.Now:yyyyMMddHHmmss}.png";
                    string photoFileName = $"Photo_{DateTime.Now:yyyyMMddHHmmss}.jpg";
    
                    // 获取保存签名和照片的文件夹路径
                    string saveFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
    
                    // 创建签名图片文件
                    SaveSignatureToFile(strokes, Path.Combine(saveFolderPath, signatureFileName));
    
                    // 创建照片文件
                    SavePhotoToFile(photo, Path.Combine(saveFolderPath, photoFileName));
                }
                catch (Exception ex)
                {
                    // 处理错误,例如显示错误消息框
                    MessageBox.Show($"保存签名和照片时发生错误:{ex.Message}");
                }
            }
    
            private void SaveSignatureToFile(StrokeCollection strokes, string filePath)
            {
                // 创建一个RenderTargetBitmap用于绘制签名
                RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(400, 100, 96, 96, PixelFormats.Default);
                renderTargetBitmap.Render(SignatureCanvas);
    
                // 创建一个PngBitmapEncoder保存签名
                PngBitmapEncoder encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
    
                // 将签名保存到文件
                using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
                {
                    encoder.Save(fileStream);
                }
            }
    
            private void SavePhotoToFile(BitmapSource photo, string filePath)
            {
                // 创建一个JpegBitmapEncoder保存照片
                JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(photo));
    
                // 将照片保存到文件
                using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
                {
                    encoder.Save(fileStream);
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

      生成唯一的文件名,然后获取用于保存的文件夹路径(这里以"我的图片"文件夹为例)。接下来,它使用RenderTargetBitmap将签名画布渲染为位图,然后使用PngBitmapEncoder保存签名。同时,也使用JpegBitmapEncoder保存相机拍摄的照片。

      创建CameraCapture.cs类来处理相机操作。你需要使用WPF的MediaElement和System.Windows.Media.Imaging来实现相机预览和拍照功能。这里提供一个简化的示例,实际应用中需要更多的处理和错误处理。

      当你需要在WPF应用中初始化相机并进行拍照时,你可以使用MediaCapture类来实现。下面是更详细的示例,展示如何初始化相机并进行拍照:

    using System;
    using System.Windows.Controls;
    using System.Windows.Media.Imaging;
    using System.Windows.Media;
    using System.Windows.Threading;
    using System.Windows;
    using System.IO;
    using System.Threading.Tasks;
    using Windows.Media.Capture;
    using Windows.Media.MediaProperties;
    using Windows.Storage;
    using Windows.Storage.Streams;
    
    namespace SignatureCaptureApp
    {
        public class CameraCapture
        {
            private MediaElement _cameraPreview;
            private MediaCapture _mediaCapture;
    
            public CameraCapture(MediaElement cameraPreview)
            {
                _cameraPreview = cameraPreview;
            }
    
            public async void InitializeCamera()
            {
                try
                {
                    // 初始化MediaCapture对象
                    _mediaCapture = new MediaCapture();
                    await _mediaCapture.InitializeAsync();
    
                    // 将相机预览显示在MediaElement中
                    _cameraPreview.SetMediaPlayer(_mediaCapture);
    
                    // 启动相机预览
                    await _mediaCapture.StartPreviewAsync();
                }
                catch (Exception ex)
                {
                    // 处理错误,例如显示错误消息框
                    MessageBox.Show($"初始化相机时发生错误:{ex.Message}");
                }
            }
    
            public async Task<BitmapSource> CapturePhoto()
            {
                try
                {
                    // 创建一个临时文件来保存照片
                    StorageFile photoFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("TempPhoto.jpg", CreationCollisionOption.GenerateUniqueName);
    
                    // 拍照并保存到临时文件
                    ImageEncodingProperties imageProperties = ImageEncodingProperties.CreateJpeg();
                    await _mediaCapture.CapturePhotoToStorageFileAsync(imageProperties, photoFile);
    
                    // 从临时文件中读取照片数据
                    using (IRandomAccessStream photoStream = await photoFile.OpenReadAsync())
                    {
                        // 创建一个BitmapDecoder来解码照片数据
                        BitmapDecoder decoder = await BitmapDecoder.CreateAsync(photoStream);
    
                        // 将照片解码为BitmapSource
                        SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync();
                        SoftwareBitmap softwareBitmapBGR8 = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
                        BitmapSource photo = await ConvertToBitmapSource(softwareBitmapBGR8);
    
                        // 删除临时文件
                        await photoFile.DeleteAsync();
    
                        // 返回照片
                        return photo;
                    }
                }
                catch (Exception ex)
                {
                    // 处理错误,例如显示错误消息框
                    MessageBox.Show($"拍照时发生错误:{ex.Message}");
                    return null;
                }
            }
    
            private async Task<BitmapSource> ConvertToBitmapSource(SoftwareBitmap softwareBitmap)
            {
                // 创建一个WriteableBitmap来保存照片数据
                WriteableBitmap bitmap = new WriteableBitmap(softwareBitmap.PixelWidth, softwareBitmap.PixelHeight);
                softwareBitmap.CopyToBuffer(bitmap.PixelBuffer);
    
                // 等待UI线程空闲,然后在UI线程上创建BitmapSource
                await Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                {
                    bitmap.Invalidate();
                }), DispatcherPriority.ApplicationIdle);
    
                return bitmap;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99

      在InitializeCamera方法中,我们使用MediaCapture类来初始化相机,并将相机预览显示在MediaElement中。在CapturePhoto方法中,我们使用CapturePhotoToStorageFileAsync方法拍照并将照片保存到临时文件中。然后,我们使用BitmapDecoder类解码照片数据,并将其转换为BitmapSource对象。最后,我们删除临时文件并返回照片。

      请注意,这段代码使用了异步方法,因此需要在方法前面加上async关键字,并使用await关键字来等待异步操作完成。此外,我们还使用了SoftwareBitmap和WriteableBitmap来处理照片数据。


      码文不易,本篇文章就介绍到这里,如果想要学习更多Java系列知识点击关注博主,博主带你零基础学习Java知识。与此同时,对于日常生活有困扰的朋友,欢迎阅读我的第四栏目《国学周更—心性养成之路》,学习技术的同时,我们也注重了心性的养成。

    在这里插入图片描述

  • 相关阅读:
    逍遥自在学C语言 | 关系运算符
    关于HarmonyOS元服务的主题演讲与合作签约
    视频评价工具AVQT介绍
    【ubuntu-nginx安装】
    Linux基础 - Web服务基础
    STM32微控制器的低功耗模式
    LIO-SAM论文与代码阅读笔记(二)代码阅读:imuPreintergration.cpp和imageProjection.cpp
    tensorflow fashion_mnist数据集模型训练及预测
    Dart(12)-异常
    学习尚硅谷HTML+CSS总结
  • 原文地址:https://blog.csdn.net/hh867308122/article/details/133910261