欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

C# 使用攝像頭拍照 支持Win7 64位

系統 2937 0
原文: C# 使用攝像頭拍照 支持Win7 64位

So, how do we capture an image from a WebCam?

Once you download the source code that is attached to the article you should have the following three projects:

  • Demo – simple Windows Forms project that demonstrates how a WebCam is used. It references WebCamWrapper which in turn references WebCamLib.
  • WebCamLib – this is where the magic is happening – it is a C++ project with just two files ( WebCamLib.h ?and WebCamLib.cpp ) that queries a WebCam using DirectShow and returns results.
  • WebCamWrapper – a C# wrapper on top of the C++ project that enables easy integration into the .NET world.

For a starting point I recommend a code view of? Demo\MainForm.cs . This form implements most of the operations you can think of when it comes to WebCam access. First is the iteration through the WebCams hooked up to the computer:

      private void MainForm_Load(object sender, EventArgs e)

{

    if (!DesignMode)

    {

        comboBoxCameras.Items.Clear();

        foreach (Camera cam in CameraService.AvailableCameras)

            comboBoxCameras.Items.Add(cam);



        if (comboBoxCameras.Items.Count > 0)

            comboBoxCameras.SelectedIndex = 0;

    }

}
    

The? CameraService ?class you see in the code is contained in the WebCamWrapper project and is the main wrapper over the main class? CameraMethods ?that is the only class implemented in the C++ WebCamLib project. CameraService ?exposes? AvailableCameras ?as a list of? Camera ?classes that contain the logic for a certain WebCam. Once the user makes a choice of camera, you’ll obviously want to start the capture:

      private CameraFrameSource _frameSource;

private static Bitmap _latestFrame;



private void btnStart_Click(object sender, EventArgs e)

{

    if (_frameSource != null && _frameSource.Camera == comboBoxCameras.SelectedItem)

        return;



    thrashOldCamera();

    startCapturing();

}


    

_frameSource ?is the variable in which we’ll save the currently selected? Camera . Touchless developers decided not to tie their capture source exclusively to WebCam (good choice obviously) so they made a generic? IFrameSource interface that? CameraFrameSource ?implements… and that’s how this class ended up as a container instead of the Camera ?class directly. The rest of the code is pretty self-explanatory – if we select the same frame source, we’ll just exit; if not we will thrash the old camera and start a new one. Onto the? startCapturing ?method:

      private void startCapturing()

{

    try

    {

        Camera c = (Camera)comboBoxCameras.SelectedItem;

        setFrameSource(new CameraFrameSource(c));

        _frameSource.Camera.CaptureWidth = 320;

        _frameSource.Camera.CaptureHeight = 240;

        _frameSource.Camera.Fps = 20;

        _frameSource.NewFrame += OnImageCaptured;



        pictureBoxDisplay.Paint += new PaintEventHandler(drawLatestImage);

        _frameSource.StartFrameCapture();

    }

    catch (Exception ex)

    {

        comboBoxCameras.Text = "Select A Camera";

        MessageBox.Show(ex.Message);

    }

}



private void setFrameSource(CameraFrameSource cameraFrameSource)

{

    if (_frameSource == cameraFrameSource)

        return;



    _frameSource = cameraFrameSource;

}



private void drawLatestImage(object sender, PaintEventArgs e)

{

    if (_latestFrame != null)

    {

        e.Graphics.DrawImage(_latestFrame, 0, 0, _latestFrame.Width, _latestFrame.Height);

    }

}



public void OnImageCaptured(Touchless.Vision.Contracts.IFrameSource frameSource, 

                            Touchless.Vision.Contracts.Frame frame, double fps)

{

    _latestFrame = frame.Image;

    pictureBoxDisplay.Invalidate();

}


    

We start off by fetching the selected? Camera ?from the? ComboBox ?which we then use to create and set the CameraFrameSource . Lines after that influence the capture parameters (be sure to remember these three lines as we will be getting back to them later) and after that we have a subscription to two events.

The first event,? NewFrame , is raised whenever WebCamLib captures an image from the WebCam. As you can see, we save that image into a local variable? _latestFrame ?and from there you can do any additional image processing you like. The second event is just a fancy (and more efficient) way of saying? pictureBoxDisplay.Image = frame.Image . For some reason, setting the? Image ?property on a PictureBox too often causes flicker and we obviously do not want that – instead we resort to invalidating the? PictureBox ?and then handling its paint event to draw the current image from the WebCam.

Now that all that is implemented, we just? StartFrameCapture ?and enjoy the view from our WebCam. Try it out – press F5 and then click the ‘Start’ button once the Form loads up.

Rent is too damn high

When you grow tired of watching yourself, simply close the form. Once you are back in Visual Studio, check out the thrashOldCamera ?method (that is utilized from the? Form_Closing ?and? btnStop_Click ?methods also):

      private void thrashOldCamera()

{

    if (_frameSource != null)

    {

        _frameSource.NewFrame -= OnImageCaptured;

        _frameSource.Camera.Dispose();

        setFrameSource(null);

        pictureBoxDisplay.Paint -= new PaintEventHandler(drawLatestImage);

    }

}


    

Well, nothing too fancy – we unsubscribe from the two mentioned events, set the? _frameSource ?variable to? null , and call? Dispose ?on? Camera ?so that the C++ WebCamLib can perform cleanup operations.

Believe it or not – that’s it. There is nothing more critical to explain or implement in order to use images from your WebCam in C#. The extra code that exists in? MainForm.cs ?is just there for saving the current image:

      private void btnSave_Click(object sender, EventArgs e)

{

    if (_frameSource == null)

        return;



    Bitmap current = (Bitmap)_latestFrame.Clone();

    using (SaveFileDialog sfd = new SaveFileDialog())

    {

        sfd.Filter = "*.bmp|*.bmp";

        if (sfd.ShowDialog() == DialogResult.OK)

        {

            current.Save(sfd.FileName);

        }

    }



    current.Dispose();

}


    

And bringing up the configuration dialog:

      private void btnConfig_Click(object sender, EventArgs e)

{

    // snap camera

    if (_frameSource != null)

        _frameSource.Camera.ShowPropertiesDialog();

}


    

Configuration Dialog

Problem(s)

As you can see from the code – the implementation is pretty easy and clean (unlike some other approaches that use WIA, obscure DLLs, clipboard, or hard disk for saving images, etc.), meaning that there are not many problems. Actually, currently there is only one problem I can identify. You remember these three lines?

?
    _frameSource.Camera.CaptureWidth = 
    
      320
    
    ;

_frameSource.Camera.CaptureHeight = 
    
      240
    
    ;

_frameSource.Camera.Fps = 
    
      20
    
    ;
  

Well, it turns out that they are not working as advertised. First, let’s talk about FPS. If we dive into the? Camera ?class (line 254) here is what we will see (the method that gets called after an image is captured from the webcam):

        private void ImageCaptured(Bitmap bitmap)

{

    DateTime dtCap = DateTime.Now;



    // Always save the bitmap

    lock (_bitmapLock)

    {

        _bitmap = bitmap;

    }



    // FPS affects the callbacks only

    if (_fpslimit != -1)

    {

        if (_dtLastCap != DateTime.MinValue)

        {

            double milliseconds = ((dtCap.Ticks - _dtLastCap.Ticks) / TimeSpan.TicksPerMillisecond) * 1.15;

            if (milliseconds + _timeBehind >= _timeBetweenFrames)

            {

                _timeBehind = (milliseconds - _timeBetweenFrames);

                if (_timeBehind < 0.0)

                {

                    _timeBehind = 0.0;

                }

            }

            else

            {

                _timeBehind = 0.0;

                return; // ignore the frame

            }

        }

    }



    if (OnImageCaptured != null)

    {

        var fps = (int)(1 / dtCap.Subtract(_dtLastCap).TotalSeconds);

        OnImageCaptured.Invoke(this, new CameraEventArgs(bitmap, fps));

    }



    _dtLastCap = dtCap;

}


      

Even if you just glanced at the method, you probably saw that most of it is dedicated to calculating the time between frames and ditching the frame if it came too soon. Which is not too bad, I guess – controlling the frame rate on C# level rather than on hardware level will probably not kill you.

But what about finding out the other two lines, which influence the size of the captured image, also not working (line 235 in? Camera.cs )?

        private void CaptureCallbackProc(int dataSize, byte[] data)

{

    // Do the magic to create a bitmap

    int stride = _width * 3;

    GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);

    var scan0 = (int)handle.AddrOfPinnedObject();

    scan0 += (_height - 1) * stride;

    var b = new Bitmap(_width, _height, -stride, PixelFormat.Format24bppRgb, (IntPtr)scan0);

    b.RotateFlip(_rotateFlip);

    // Copy the image using the Thumbnail function to also resize if needed

    var copyBitmap = (Bitmap)b.GetThumbnailImage(_width, _height, null, IntPtr.Zero);

    //var copyBitmap = (Bitmap)b.Clone();



    // Now you can free the handle

    handle.Free();



    ImageCaptured(copyBitmap);

}


      

As you can see, the image size is actually faked. Majority of cameras I’ve tested out will tend to return images in the 640x480 size. Which is fine in most cases – if you need a smaller image,? b.GetThumbnailImage ?will allow you to easily resize it. However, if you wish a higher resolution image, you are stuck and that’s not a good thing.

So, anyone from the C++ world is more than welcome to help with this. The following links I’ve read gave me the impression that all that’s needed to be done is somehow invoke the Video Format window in C++, the same way we are now invoking the Video Source Configuration window (for setting Brightness, Contracts, etc):

    • Setting up Webcam properties with DirectShow forum post
    • EasyWebCam project ?– for most part it is bad, but it does have a Video Format window. I decompiled WebCam_Capture.dll ?from the project only to find out that everything is implemented using PInvoke - meaning that it’s useless for our approach. So, if somebody can bring up that same window using C++ and DirectShow – please help out by extending the existing? CameraMethods ?class.

Video Format Dialog

?

?

源碼下載地址: Source

?

C# 使用攝像頭拍照 支持Win7 64位


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美国产一区二区三区 | 小明天天看 | 无码色情影片视频在线看免费 | 亚洲午夜在线播放 | 国产丫丫视频私人影院 | www天天操| 亚洲色欲色欲www | 成人免费一级毛片在线播放视频 | 午夜精品一区二区三区在线观看 | 精品久久久久久亚洲 | 欧美激情精品久久久久久变态 | 精品欧美亚洲韩国日本久久 | 99九九精品视频 | 黄色的视频免费观看 | 99r精品在线 | 欧美激情图片区 | 一区二区中文字幕 | 久久亚洲欧美日韩精品专区 | 奇米 影音先锋 | 国产精品久久久久久久久久日本 | 国产主播在线看 | 亚洲综合国产 | 久久久久久免费一区二区三区 | 精品国产一区二区三区免费 | 日韩精品无码一区二区三区 | 日韩在线欧美 | 亚洲精品97福利在线 | 欧美zozozo人禽交免费观看 | 午夜影院恐怖电影免费看 | 成人久久久久爱 | 成人午夜动漫在线观看 | 成人久久网| 99热国产这里只有精品9九 | 天堂资源8中文最新版 | 久久青草精品免费资源站 | 91婷婷射 | 伊人久久99亚洲精品久久频 | av网站免费 | 日韩高清中文字幕 | 欧美在线观看视频一区 | 国产成人精品福利站 |