Самый простой способ получить bitmap с камеры на c#

220
19 ноября 2018, 03:20

Единственное, что нашел - это библиотека AFORGE.net с сэмплом SNAPSHOT MAKER. Но там реализовано и потоковое видео в контрол, и снятие битмапа, в общем очень богатый функционал, который мне в корне не понадобится. Мне нужен только битмап(причем задержка между съемками более минуты), может есть более грациозное решение для получения его с камеры?

Answer 1

Если не тащить громоздкие библиотеки вроде AForge.NET (которая все равно использует DirectShow API в примере из параллельного ответа), можно ограничиться библиотекой попроще DirectShow.NET, в которой есть по меньшей мере два близких примера:

\DirectShowSamples-2010-February\Samples\Misc\DxWebCam

A poor man's web cam program. This application runs as a Win32 Service.
It takes the output of a capture graph, turns it into a stream of JPEG files, and sends it thru TCP/IP to a client application.

\DirectShowSamples-2010-February\Samples\Capture\DxSnap

Use DirectShow to take snapshots from the Still pin of a capture device. Note the MS encourages you to use WIA for this, but if you want to do in with DirectShow and C#, here's how.

Note that this sample will only work with devices that output uncompressed video as RBG24. This will include most webcams, but probably zero tv tuners.

В обоих случаях происходит примерно похожее: инициализация захвата видео с камеры и дальнейшая работа с кадрами (далее с видео - по вкусу: пропуск ненужного, обработка нужного).

Нужно иметь в виду следующее: у веб-камер есть нередко неприятная особенность долго начинать работу (инициализация, фокусировка и настройка баланса белого и пр.). То есть для моментального снимка нужно все время снимать и выбрасывать ненужные кадры, далее по сигналу схватить первый попавшийся (или последний имеющийся) кадр.

Answer 2

Посмотрите вот это решение MJPEG Decoder

оно более легкое по перфе. Нет ничего лишнего. Ушел с Aforge на него.

Так же открыт исходный код для исследования.

UPD Либо, как советуют люди, вот так

        var sourceURL = "http://192.168.137.23/cgi-bin/viewer/video.jpg";
        var buffer = new byte[100000];
        int read, total = 0;
        var req = (HttpWebRequest)WebRequest.Create(sourceURL);
        var resp = req.GetResponse();
        var stream = resp.GetResponseStream();
        while (stream != null && (read = stream.Read(buffer, total, 1000)) != 0)
            total += read;
        pictureBox1.Image = (Bitmap)Image.FromStream(new MemoryStream(buffer, 0, total));

sourceURL - зависит от камеры, по какому пути она отдает одиночный jpg

Answer 3

Используя Aforge сделал следующим образом. (Snapshot,почему-то не срабатывало событие trigger камеры)

public class VideoGrabber
{
    VideoCaptureDevice videoSource;
    Bitmap b = null;
    public bool isRunning = false;
    public Bitmap takeSnapshot()
    {
        isRunning = true;
        b = null;
        videoSource.NewFrame += new AForge.Video.NewFrameEventHandler(videoSource_NewFrame);
        while (b == null)
            System.Threading.Thread.Sleep(1);
        videoSource.NewFrame -= new AForge.Video.NewFrameEventHandler(videoSource_NewFrame);
        isRunning = false;
        return b;
    }
    public VideoGrabber()
    {
        FilterInfoCollection videosources = new FilterInfoCollection(FilterCategory.VideoInputDevice);
        if (videosources != null)
        {
            videoSource = new VideoCaptureDevice(videosources[0].MonikerString);
            try
            {
                if (videoSource.VideoCapabilities.Length > 0)
                {
                    string highestSolution = "0;0";
                    for (int i = 0; i < videoSource.VideoCapabilities.Length; i++)
                    {
                        if (videoSource.VideoCapabilities[i].FrameSize.Width > Convert.ToInt32(highestSolution.Split(';')[0]))
                            highestSolution = videoSource.VideoCapabilities[i].FrameSize.Width.ToString() + ";" + i.ToString();
                    }
                    videoSource.VideoResolution = videoSource.VideoCapabilities[Convert.ToInt32(highestSolution.Split(';')[1])];
                }
                videoSource.Start();
            }
            catch { }
        }
    }
    void videoSource_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
    {
        b = (Bitmap)eventArgs.Frame.Clone();
    }
    public void Dispose()
    {
        if (videoSource != null && videoSource.IsRunning)
        {
            videoSource.SignalToStop();
            videoSource = null;
        }
    }
}

Снимок получаю за 1-3 секунды. Хотелось бы снимок за 100-300 мс.

READ ALSO
Запрос с опциональными OrderBy, Where и Take

Запрос с опциональными OrderBy, Where и Take

Хочу сделать пагинацию с фильтром (любое условие) и сортировкой по любому полю

189
Работа с изображением через System.Windows.Media VS System.Drawing

Работа с изображением через System.Windows.Media VS System.Drawing

Подскажите, каким пространством при работе с изображениями лучше пользоваться в новых проектах?

197
В списке using отсутствует OpenQA.Selenium.PhantomJS

В списке using отсутствует OpenQA.Selenium.PhantomJS

Хотел начать работать с PhantomJS, установил через nuget сам Selenium, SeleniumPhantomJS

183
При создании сервиса на Linux нет соединения с БД Oracle

При создании сервиса на Linux нет соединения с БД Oracle

Возникла проблема при создании сервиса(systemd) в Linux для автоматического запуска Web App: нет никаких признаков соединения с Oracle БД

203