0

我目前正在学习 QR 码网络摄像头解码器。我从https://zxingnet.svn.codeplex.com/svn/trunk/Clients/AForgeDemo/中举了一个例子,并成功构建它而没有错误。但是,当我在连接网络摄像头的情况下运行它时,没有输入,或者它不会打开网络摄像头。根据我的理解,当用户在组合框中选择网络摄像头时,它会打开。好吧,由于构建时没有错误,我无法确定出了什么问题。我还查看了一个项目,当用户按下按钮时会打开网络摄像头,我计划将其实施到当前项目中。我已经插入了按钮,但我不知道我应该在按钮上编程什么来打开网络摄像头,而不是在组合框中选择

有人会建议或指导我完成它。下面是主程序和2类

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using AForge.Video;
    using ZXing;
    using System.Threading;

命名空间 AForgeDemo { 公共部分类 AForgeDemoForm :表单 {

    private struct Device
    {
        public int Index;
        public string Name;
        public override string ToString()
        {
            return Name;
        }
    }

    private readonly CameraDevices camDevices;
    private Bitmap currentBitmapForDecoding;
    private readonly Thread decodingThread;
    private Result currentResult;
    private readonly Pen resultRectPen;

    public AForgeDemoForm()
    {
        InitializeComponent();
        camDevices = new CameraDevices();

        decodingThread = new Thread(DecodeBarcode);
        decodingThread.Start();

        pictureBox1.Paint += pictureBox1_Paint;
        resultRectPen = new Pen(Color.Green, 10);
    }

    void pictureBox1_Paint(object sender, PaintEventArgs e)
  {
     if (currentResult == null)
        return;

     if (currentResult.ResultPoints != null && currentResult.ResultPoints.Length > 0)
     {
        var resultPoints = currentResult.ResultPoints;
        var rect = new Rectangle((int)resultPoints[0].X, (int)resultPoints[0].Y, 1, 1);
        foreach (var point in resultPoints)
        {
           if (point.X < rect.Left)
              rect = new Rectangle((int)point.X, rect.Y, rect.Width + rect.X -            (int)point.X, rect.Height);
           if (point.X > rect.Right)
              rect = new Rectangle(rect.X, rect.Y, rect.Width + (int)point.X - rect.X, rect.Height);
           if (point.Y < rect.Top)
              rect = new Rectangle(rect.X, (int)point.Y, rect.Width, rect.Height + rect.Y - (int)point.Y);
           if (point.Y > rect.Bottom)
              rect = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height + (int)point.Y - rect.Y);
        }
        using (var g = pictureBox1.CreateGraphics())
        {
           g.DrawRectangle(resultRectPen, rect);
        }
}

} 受保护的覆盖无效 OnLoad(EventArgs e) { base.OnLoad(e); LoadDevicesToCombobox(); }

    protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
    {
        base.OnClosing(e);
        if (!e.Cancel)
        {
            decodingThread.Abort();
            if (camDevices.Current != null)
            {
                camDevices.Current.NewFrame -= Current_NewFrame;
                if (camDevices.Current.IsRunning)
                {
                    camDevices.Current.SignalToStop();
                }
            }
        }
    }

    private void LoadDevicesToCombobox()
    {
        cmbDevice.Items.Clear();
        for (var index = 0; index < camDevices.Devices.Count; index++)
        {
            cmbDevice.Items.Add(new Device { Index = index, Name = camDevices.Devices[index].Name });
        }
    }

    private void cmbDevice_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (camDevices.Current != null)
        {
            camDevices.Current.NewFrame -= Current_NewFrame;
            if (camDevices.Current.IsRunning)
            {
                camDevices.Current.SignalToStop();
            }
        }

        camDevices.SelectCamera(((Device)(cmbDevice.SelectedItem)).Index);
        camDevices.Current.NewFrame += Current_NewFrame;
        camDevices.Current.Start();
    }

    private void Current_NewFrame(object sender, NewFrameEventArgs eventArgs)
    {
        if (IsDisposed)
        {
            return;
        }

        try
        {
            if (currentBitmapForDecoding == null)
            {
                currentBitmapForDecoding = (Bitmap)eventArgs.Frame.Clone();
            }
            Invoke(new Action<Bitmap>(ShowFrame), eventArgs.Frame.Clone());
        }
        catch (ObjectDisposedException)
        {
            // not sure, why....
        }
    }

    private void ShowFrame(Bitmap frame)
    {
        if (pictureBox1.Width < frame.Width)
        {
            pictureBox1.Width = frame.Width;
        }
        if (pictureBox1.Height < frame.Height)
        {
            pictureBox1.Height = frame.Height;
        }
        pictureBox1.Image = frame;
    }

    private void DecodeBarcode()
    {
        var reader = new BarcodeReader();
        while (true)
        {
            if (currentBitmapForDecoding != null)
            {
                var result = reader.Decode(currentBitmapForDecoding);
                if (result != null)
                {
                    Invoke(new Action<Result>(ShowResult), result);
                }
                currentBitmapForDecoding.Dispose();
                currentBitmapForDecoding = null;
            }
            Thread.Sleep(200);
        }
    }

    private void ShowResult(Result result)
    {
        currentResult = result;
        txtBarcodeFormat.Text = result.BarcodeFormat.ToString();
        txtContent.Text = result.Text;
    }

    private void button1_Click(object sender, EventArgs e)
    {

    }
}

}

cameradevice 的类

  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using AForge.Video.DirectShow;

命名空间 AForgeDemo {

    internal class CameraDevices
    {
        public FilterInfoCollection Devices { get; private set; }
        public VideoCaptureDevice Current { get; private set; }

        public CameraDevices()
        {
            Devices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
        }

        public void SelectCamera(int index)
        {
            if (index >= Devices.Count)
            {
                throw new ArgumentOutOfRangeException("index");
            }
            Current = new VideoCaptureDevice(Devices[index].MonikerString);
        }
    }
}

再次,我恳请任何人帮助我将在按钮命令中放置什么以直接激活网络摄像头,而不是从组合框中选择

太感谢了

4

1 回答 1

0

按钮后面的事件处理程序所需的代码类似于 cmbDevice_SelectedIndexChanged 方法中的代码。我认为它应该如下所示

     // select the first available camera and start capturing
     camDevices.SelectCamera(0);
     camDevices.Current.NewFrame += Current_NewFrame;
     camDevices.Current.Start();

但我认为主要的挑战是找出为什么原始示例不能按预期工作。如果在组合框的处理程序或按钮的处理程序中调用相同的代码,则没有区别。

于 2013-05-03T19:14:44.193 回答