C# winform中调用摄像头 抓到图片转成 Base64

需求
C# winform中调用摄像头 抓到图片转成 Base64

                            //得到机器所有接入的摄像设备
                          FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
                        if (videoDevices.Count == 0)
                        {
                            WriteLog("没有找到摄像头");
                        }
                        //获取摄像头
                        VideoCaptureDevice videoDevice = new VideoCaptureDevice(videoDevices[0].MonikerString);
                        //摄像头分辨率 和 设备的摄像头分辨率数组
                        VideoCapabilities[] videoCapabilities = videoDevice.VideoCapabilities;                         

                        if (videoDevice != null)//如果摄像头不为空
                        {
                            if ((videoCapabilities != null) && (videoCapabilities.Length != 0))
                            {
                                //摄像头分辨率   
                                videoDevice.VideoResolution = videoCapabilities[0];

                            }
                        }

因为是C# 后台代码,没有VideoSourcePlayer 控件。

需要直接从摄像头,里面生成图片,转成 Base64。

引用chatgpt部分指引作答:
要在C# WinForms中调用摄像头并将捕获的图像转换为Base64编码,您可以使用AForge.Video.DirectShow库来实现。以下是一个示例代码,展示了如何完成这个过程:

using AForge.Video;
using AForge.Video.DirectShow;
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace WebcamCapture
{
    public partial class Form1 : Form
    {
        private FilterInfoCollection videoDevices;
        private VideoCaptureDevice videoDevice;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);

            if (videoDevices.Count == 0)
            {
                MessageBox.Show("没有找到摄像头");
                return;
            }

            videoDevice = new VideoCaptureDevice(videoDevices[0].MonikerString);
            videoDevice.NewFrame += VideoDevice_NewFrame;
            videoDevice.Start();
        }

        private void VideoDevice_NewFrame(object sender, NewFrameEventArgs eventArgs)
        {
            // 捕获新的图像帧
            Bitmap frame = (Bitmap)eventArgs.Frame.Clone();

            // 将图像转换为Base64编码
            string base64Image = ConvertToBase64(frame);

            // 在这里使用base64Image进行进一步的处理,例如保存到文件或发送到远程服务器
        }

        private string ConvertToBase64(Bitmap image)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                byte[] imageBytes = ms.ToArray();
                return Convert.ToBase64String(imageBytes);
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (videoDevice != null && videoDevice.IsRunning)
                videoDevice.SignalToStop();
        }
    }
}

在上述示例代码中,我们使用AForge.Video.DirectShow库来调用摄像头。在窗体加载时,我们获取第一个摄像设备并启动视频捕获。每当摄像头捕获到新的帧时,我们会触发VideoDevice_NewFrame事件,将捕获的图像转换为Base64编码。

请确保在项目中引用AForge.Video和AForge.Video.DirectShow库,并添加相应的命名空间引用。

来自NewBing和LP的编写:

为了满足你的需求,要用AForge.NET库。首先要安装AForge.NET Framework库,你可以通过NuGet Package Manager来安装。以下是一个简单的例子,展示了如何捕捉摄像头的图像,并将其转换为Base64字符串:

先要添加以下的命名空间:

using AForge.Video;
using AForge.Video.DirectShow;
using System.IO;
using System.Drawing;
using System;
using System.Drawing.Imaging;

以下是一个示例代码:

private void CaptureImage()
{
    FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
    if (videoDevices.Count == 0)
    {
        Console.WriteLine("没有找到摄像头");
        return;
    }

    VideoCaptureDevice videoDevice = new VideoCaptureDevice(videoDevices[0].MonikerString);
    VideoCapabilities[] videoCapabilities = videoDevice.VideoCapabilities;

    if (videoDevice != null)
    {
        if ((videoCapabilities != null) && (videoCapabilities.Length != 0))
        {
            videoDevice.VideoResolution = videoCapabilities[0];
        }

        videoDevice.NewFrame += new NewFrameEventHandler(videoDevice_NewFrame);
        videoDevice.Start();
    }
}

void videoDevice_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
    // process new video frame and create bitmap from it
    Bitmap bitmap = eventArgs.Frame.Clone() as Bitmap;

    // process the bitmap to Base64 string
    string base64String;
    using (MemoryStream memory = new MemoryStream())
    {
        bitmap.Save(memory, ImageFormat.Jpeg);
        byte[] byteImage = memory.ToArray();
        base64String = Convert.ToBase64String(byteImage);
    }

    Console.WriteLine(base64String);

    // you should stop capturing video after getting one frame
    VideoCaptureDevice videoDevice = sender as VideoCaptureDevice;
    if (videoDevice != null && videoDevice.IsRunning)
    {
        videoDevice.SignalToStop();
        videoDevice.WaitForStop();
    }
}

例子中定义了一个名为CaptureImage的方法来初始化并启动摄像头。然后定义了一个事件处理程序videoDevice_NewFrame,当摄像头捕获到新的帧时,它将被调用。在这个事件处理程序中,创建了一个位图对象,并将其转换为Base64字符串。

注意,此代码会在捕获第一帧后停止摄像头。如果你想要连续捕获,要调整代码以满足你的需求。

  • 这篇博客: C# Winform调用百度接口实现身份证文字识别教程完整版!!!(源码)中的 第三步,绘制videoSourcePlayer控件,对身份证进行拍摄 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 现在我们是没有这个控件的,所以我们要先导包,点击我们的工具选项卡,选择NuGet包管理器,管理解决方案的NuGet程序包,安装一下的包:
    在这里插入图片描述
    然后我们就能看到videoSourcePlayer控件,把它绘制在窗体上就好了。

    在这里插入图片描述

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
可以使用C#中的DirectShow.NET库来调用摄像头,并使用System.Drawing.Bitmap来处理图像数据,最后将图像数据转换成Base64。

以下是一个可能的实现代码:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using DirectShowLib;

namespace CameraDemo
{
    public class CameraManager
    {
        private IFilterGraph2 graphBuilder;
        private ICaptureGraphBuilder2 captureGraphBuilder;
        private IBaseFilter captureFilter;
        private IAMVideoControl videoControl;
        private IAMStreamConfig streamConfig;

        private int width = 640;
        private int height = 480;
        private int fps = 30;

        public bool Initialize()
        {
            try
            {
                // 创建 Filter Graph Manager
                graphBuilder = (IFilterGraph2)new FilterGraph();
                captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();

                // 创建摄像头过滤器
                captureFilter = CreateCaptureFilter();

                // 添加过滤器到 Filter Graph
                graphBuilder.AddFilter(captureFilter, "Capture Filter");

                // 创建 Sample Grabber Filter
                var sampleGrabber = (ISampleGrabber)new SampleGrabber();
                var baseGrabFlt = (IBaseFilter)sampleGrabber;
                graphBuilder.AddFilter(baseGrabFlt, "Sample Grabber");

                // 设置 Sample Grabber 的回调函数
                var mediaEventEx = (IMediaEventEx)graphBuilder;
                var mediaControl = (IMediaControl)graphBuilder;
                var mediaEvent = (IMediaEvent)graphBuilder;
                var callback = new SampleGrabberCallback();
                sampleGrabber.SetCallback(callback, 1);

                // 连接摄像头和 Sample Grabber
                var sourceOutPin = GetOutputPin(captureFilter, 0);
                var destInPin = GetInputPin(baseGrabFlt, 0);
                graphBuilder.Connect(sourceOutPin, destInPin);

                // 设置视频格式
                streamConfig = (IAMStreamConfig)sourceOutPin;
                AMMediaType mediaType = new AMMediaType();
                streamConfig.GetFormat(out mediaType);
                var videoInfo = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader));
                videoInfo.BmiHeader.Width = width;
                videoInfo.BmiHeader.Height = height;
                videoInfo.AvgTimePerFrame = (long)(10000000.0 / fps);
                Marshal.StructureToPtr(videoInfo, mediaType.formatPtr, false);
                streamConfig.SetFormat(mediaType);

                // 运行 Filter Graph
                mediaControl.Run();

                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
        }

        public void ShutDown()
        {
            if (graphBuilder != null)
            {
                graphBuilder.Stop();
                Marshal.ReleaseComObject(graphBuilder);
                graphBuilder = null;
            }
        }

        public Bitmap Capture()
        {
            var sampleGrabber = (ISampleGrabber)graphBuilder.FilterCollection[1];
            var mediaEventEx = (IMediaEventEx)graphBuilder;
            var mediaControl = (IMediaControl)graphBuilder;

            // 设置 Sample Grabber 的参数
            var mediaType = new AMMediaType();
            sampleGrabber.GetConnectedMediaType(mediaType);
            var videoInfo = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader));
            var bufferSize = videoInfo.BmiHeader.ImageSize;
            var buffer = Marshal.AllocHGlobal(bufferSize);
            sampleGrabber.SetBufferSamples(false);
            sampleGrabber.SetOneShot(false);
            sampleGrabber.SetCallback(null, 1);

            // 抓取图像
            mediaControl.Pause();
            mediaControl.Run();
            mediaEventEx.WaitForCompletion(-1, out _);
            sampleGrabber.GetCurrentBuffer(ref bufferSize, buffer);
            mediaControl.Stop();

            // 将图像数据转换为 Bitmap
            var bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            var bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
            var data = bitmapData.Scan0;
            var src = buffer;
            for (int y = 0; y < height; y++)
            {
                var dest = (IntPtr)(data.ToInt64() + y * bitmapData.Stride);
                NativeMethods.CopyMemory(dest, src, width * 3);
                src = (IntPtr)(src.ToInt64() + videoInfo.BmiHeader.Pitch);
            }
            bitmap.UnlockBits(bitmapData);

            Marshal.FreeHGlobal(buffer);
            mediaType.Dispose();

            return bitmap;
        }

        public string CaptureAsBase64()
        {
            var bitmap = Capture();
            var stream = new MemoryStream();
            bitmap.Save(stream, ImageFormat.Png);
            var bytes = stream.ToArray();
            var base64 = Convert.ToBase64String(bytes);
            stream.Dispose();
            bitmap.Dispose();
            return base64;
        }

        private IBaseFilter CreateCaptureFilter()
        {
            var devices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            if (devices.Count == 0)
                throw new Exception("No video devices found");

            var moniker = devices[0].MonikerString;
            var filterGraph = new FilterGraph() as IFilterGraph2;
            var captureFilter = filterGraph.AddSourceFilter(moniker, "Video Capture");
            return captureFilter;
        }

        private IPin GetOutputPin(IBaseFilter filter, int pinIndex)
        {
            var pinEnum = (IEnumPins)filter.EnumPins();
            var pins = new IPin[1];
            pinEnum.Next(pins.Length, pins, out _);
            return pins[pinIndex];
        }

        private IPin GetInputPin(IBaseFilter filter, int pinIndex)
        {
            var pinEnum = (IEnumPins)filter.EnumPins();
            var pins = new IPin[1];
            pinEnum.Next(pins.Length, pins, out _);

            IPin connectedPin = null;
            var pinDir = new PinDirection();
            pins[pinIndex].QueryDirection(out pinDir);
            if (pinDir == PinDirection.Output)
            {
                var pinInfo = new PinInfo();
                pins[pinIndex].QueryPinInfo(out pinInfo);
                var pinConnectedTo = pinInfo.pFilter.FindPin(pinInfo.achName);
                connectedPin = GetInputPin(pinConnectedTo, 0);
                Marshal.ReleaseComObject(pinConnectedTo);
            }
            else
            {
                pins[pinIndex].ConnectedTo(out connectedPin);
            }
            return connectedPin;
        }

        private class SampleGrabberCallback : ISampleGrabberCB
        {
            public int SampleCB(double sampleTime, IMediaSample pSample)
            {
                return 0;
            }

            public int BufferCB(double sampleTime, IntPtr pBuffer, int bufferLen)
            {
                return 0;
            }
        }
    }

    internal static class NativeMethods
    {
        [DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory")]
        public static extern void CopyMemory(IntPtr dest, IntPtr src, int length);
    }
}

在使用摄像头之前,需要在项目中添加对DirectShow.NET库的引用。可以通过NuGet包管理器来添加DirectShowLib库的引用。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

videoDevice.NewFrame += new NewFrameEventHandler(VideoNewFrame);

private void VideoNewFrame(object sender, NewFrameEventArgs eventArgs)
{
    var bitmap = (Bitmap)eventArgs.Frame.Clone();
    var base64String = ImageToBase64(bitmap);
}

private string ImageToBase64(Image image)
{
    using (MemoryStream memoryStream = new MemoryStream())
    {
        image.Save(memoryStream, image.RawFormat);
        byte[] imageBytes = memoryStream.ToArray();
        string base64String = Convert.ToBase64String(imageBytes);
        return base64String;
    }
}