Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.05.22;
Скачать: [xml.tar.bz2];

Вниз

фото с вебкамеры.   Найти похожие ветки 

 
vegarulez   (2011-02-02 18:27) [0]

Привет всем!
комрады, подскажите такой вопрос, как можно с вебкамеры сделать снимок просто в jpg файл к примеру. Код для захвата видео - нашел - он работает - теперь вопрос как мне по событию - допустим по нажатию на кнопку делать снимок с вебкамры.


unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls,ShellAPI;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   Panel1: TPanel;
   Timer1: TTimer;
   Button3: TButton;
   procedure Button1Click(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   procedure Timer1Timer(Sender: TObject);
   procedure Button3Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;
const WM_CAP_START = WM_USER;
WM_CAP_STOP = WM_CAP_START + 68;
WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
WM_CAP_SAVEDIB = WM_CAP_START + 25;
WM_CAP_GRAB_FRAME = WM_CAP_START + 60;
WM_CAP_SEQUENCE = WM_CAP_START + 62;
WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20;

function capCreateCaptureWindowA(lpszWindowName : PCHAR;
dwStyle : longint;
x : integer;
y : integer;
nWidth : integer;
nHeight : integer;
ParentWin : HWND;
nId : integer): HWND;
stdcall external "AVICAP32.DLL";
var
 Form1: TForm1;

implementation
{$R *.dfm}

var hWndC : THandle;

procedure TForm1.Button1Click(Sender: TObject);
begin
hWndC := capCreateCaptureWindowA("My Own Capture Window",
WS_CHILD or WS_VISIBLE ,
0,
0,
Panel1.Width,
Panel1.Height,
Panel1.Handle,
0); //создаем область для вывода получаемых в будущем картинок =)

if hWndC <> 0 then //если при создании области ошибок не возникло, то сопкойно начинаем забирать данный с веб-камеры
SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);  //забираем картинку с вебкамеры

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 hWndC := 0;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 if hWndC <> 0 then
 begin
   SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);  //"отключаемся" от веб-камеры
   hWndC := 0;
 end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if hWndC <> 0 then SendMessage(hWndC, WM_CAP_GRAB_FRAME, 0, 0); //забираем картинку с вебкамеры
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  // снимок в jpg
end;

end.


 
И. Павел ©   (2011-02-02 19:28) [1]

Наверное, можно использовать не панель, а что-нибудь с канвой, и оттуда читать пиксели. Правда, это кривовато. Лучше использовать DSPack.


 
vegarulez   (2011-02-02 20:12) [2]

Я конечно чайник в этом вопросе
раз там изображение выдаётся на канву TPanel, то как при нажатии на кнопку загружать канву Tpanel`а в Timage а  там уже есть допустим процедура savetofile. Соответсвенно тогда вопрос как взять изображение в Tpanel и поместить в Timage


 
И. Павел ©   (2011-02-02 20:27) [3]

Используйте не Panel, а, например, TForm. У формы есть канва. Ее можно прочитать и скопировать на другую канву. Т.е. создайте Form2 и в capCreateCaptureWindowA передавайте именно ее дескриптор (хотя для теста можно и Form1 использовать).

Но, ИМХО, все же лучше взглянуть в сторону DSPack.


 
i_p_pavel@mail.ru   (2011-02-02 20:28) [4]

А у TPanel канвы нет.


 
vegarulez   (2011-02-02 20:32) [5]

так  сохраниение вроде сделал
нашел кусочек кода - вставил всё рабит

procedure TForm1.Button3Click(Sender: TObject);
var
 saveDialog1 : TSaveDialog;
begin
 saveDialog1 := TSaveDialog.Create(self);
  // снимок в jpg
if hWndC <> 0 then begin
  SaveDialog1.DefaultExt := "bmp";
  SaveDialog1.Filter := "Bitmap files (*.bmp)|*.bmp";
  if SaveDialog1.Execute then
    SendMessage(hWndC,
                WM_CAP_SAVEDIB,
                0,
                longint(pchar(SaveDialog1.FileName)));

end;
end;


вопрос как тоже самое сохранять в jpg формате?


 
И. Павел ©   (2011-02-02 20:40) [6]


> вопрос как тоже самое сохранять в jpg формате?

Если использовать этот способ, то, очевидно, нужно загрузить bmp-файл в битмап и конвертировать его вот так:
http://delphidevelop.ru/publ/15-1-0-163
А потом bitmep удалить. Хотя не понятно, зачем такие сложности.


 
И. Павел ©   (2011-02-02 20:53) [7]

Еще можно почитать msdn и использовать callback функцию, сapVideoStreamCallback, которая:

> used with streaming capture to optionally process a frame
> of captured video.


 
vegarulez   (2011-02-02 22:17) [8]

Так в Tbitmap можно же загрузить сразу из hWndC.
и произвести сразу конвертацию. и сохранить уже конвертированный файл.
Подскажите как это сделать.


 
vegarulez   (2011-02-02 22:20) [9]

грубо говоря как вот это

    SendMessage(hWndC,
                WM_CAP_SAVEDIB,
                0,
                longint(pchar(SaveDialog1.FileName)));


поместить в tbitmap.
я так понимаю в SendMesssage только указатели.
Комрады как в tbitmap залить по этим указателям?


 
И. Павел ©   (2011-02-02 22:27) [10]


> я так понимаю в SendMesssage только указатели.
> Комрады как в tbitmap залить по этим указателям?

В Send Message нет никаких указателей на битмапы. Это просто функция отправки сообщения WM_CAP_SAVEDIB. Ей передается дескриптор окна, код сообщения и два параметра - и все. Чужое окно принимает это сообщение и сохраняет фрейм в файл. Ваша программа в этом сохранении не учавствует.

Чем вам не нравятся DSPack? Вы попробовали [7]?


 
vegarulez   (2011-02-02 22:34) [11]

Наверно нужно создать переменную TMemoryStream туда скинуть а потом с помощью LoadFromStream загрузить это всё в TBitmap.
Комрады подскажите синтаксис как всё это сделать...  идея есть - реализация хромает ))


 
И. Павел ©   (2011-02-02 22:39) [12]

Вспоминается бородатый анекдот:
- Доктор, помогите! Мне кажется, что все люди меня просто игнорируют...
- Следующий!


 
vegarulez   (2011-02-02 22:46) [13]

И. Павел ©   (02.02.11 22:27) [10]
неа не пробовал.

можно
сделать через
bitblt
подскажите по синтаксису. плз.


 
vegarulez   (2011-02-02 22:47) [14]

И. Павел ©   (02.02.11 22:39) [12]
долго разбираться. Мне нужно ещё вчера. не игнорируют просто уже практически всё готово - нужно лишь сохранять не в bmp а в jpg.
Не хватает знаний - чтобы это правильно сделать.


 
vegarulez   (2011-02-02 22:50) [15]

Пытаюсь передать дескриптор окна -

 bitblt(bmp.Canvas.Handle, 0, 0, Panel1.Width, Panel1.Height,
   hWndC, 0, 0, SRCCOPY);


но сохраняет почему то в таком случае файл в котором всё белое.
Как правильно это сделать?


 
DVM ©   (2011-02-02 23:21) [16]

Для одиночных кадров с камер удобнее использовать twain - почти все драйвера поддерживают twain интерфейс.

Video for Windows устарело, лучше использовать Direct Show.


 
vegarulez   (2011-02-02 23:31) [17]

ок - ну это всё потом.
сейчас подскажите как мне кадр сохранить в jpg файл.


 
vegarulez   (2011-02-02 23:35) [18]

пытаюсь вместо tpanel сделать сразу через bmp

procedure TForm1.AllClick(Sender: TObject);
var
 bmp:tbitmap;
 jpg:TJPEGImage;
begin

 bmp := TBitMap.Create;
 bmp.Height:=240;
 bmp.Width:=320;

hWndC := capCreateCaptureWindowA("My Own Capture Window",
WS_CHILD or WS_VISIBLE ,
0,
0,
bmp.Width,
bmp.Height,
bmp.Handle,
0); //создаем область для вывода получаемых в будущем картинок =)

 if hWndC <> 0 then //если при создании области ошибок не возникло, то сопкойно начинаем забирать данный с веб-камеры
  SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);  //забираем картинку с вебкамеры
 if hWndC <> 0 then
  SendMessage(hWndC, WM_CAP_GRAB_FRAME, 0, 0); //забираем картинку с вебкамеры
 jpg := BMP_To_JPG(bmp);
 jpg.SaveToFile("./123.jpg");
 if hWndC <> 0 then
 begin
   SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);  //"отключаемся" от веб-камеры
   hWndC := 0;
 end;
end;


но hWndC=0
((((
что делаю не так?


 
DVM ©   (2011-02-02 23:35) [19]


> vegarulez   (02.02.11 22:50) [15]


> bitblt(bmp.Canvas.Handle, 0, 0, Panel1.Width, Panel1.Height,
>
>    hWndC, 0, 0, SRCCOPY);

Ты читал в справке про параметры функции bitblt? Какой к лешему hWndC ?


 
vegarulez   (2011-02-02 23:51) [20]

DVM ©   (02.02.11 23:35) [19]
палин ну не шарю.
Пытаюсь сделать как можно быстрее.

Подскажи про
vegarulez   (02.02.11 23:35) [18]


 
vegarulez   (2011-02-09 23:25) [21]

Комрады...
ну так всё же как передать в BMP_To_JPG картинку с TPanel?


 
KilkennyCat ©   (2011-02-10 01:14) [22]


>
> но hWndC=0

в каком месте-то?


 
И. Павел ©   (2011-02-10 08:37) [23]

> [21] vegarulez   (09.02.11 23:25)

Вот что значит заранее четко и жестко сформульрована задача: захват картинки именно с TPanel и ни шагу в сторону :) И никаких там TForm с удобными канвасами, сторонних компонент и WinAPI - все это для слабаков, не умеющих решать задачи собственными силами :)


 
vegarulez   (2011-02-10 22:12) [24]

c WinAPI разбираться надо долго и упорно - для меня это какой-то страшный лес куда даже заходить боюсь ибо потеряюсь там... (


 
vegarulez   (2011-02-10 22:14) [25]

Сделал вот так:

procedure TForm1.Button3Click(Sender: TObject);
var
 bmp:tbitmap;
 jpg:TJPEGImage;
begin

 // снимок в jpg
if hWndC <> 0 then begin
   SendMessage(hWndC,
               WM_CAP_SAVEDIB,
               0,
               longint(pchar("./123.bmp")));
bmp := TBitMap.Create;
bmp.LoadFromFile("./123.bmp");
jpg := BMP_To_JPG(bmp);
jpg.SaveToFile("./123.jpg");
end;
end;


криво. но по другому не умею... поэтому нид хелп.


 
Студент   (2011-02-10 23:16) [26]


> SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);  //забираем
> картинку с вебкамеры


Это в смысле "забираем картинку"? Тут же прям в константе написано - "подключиться к драйверу"...

Я вообще не понимаю в чём проблема-то? С веб-камерами не работал, но тут же есть и hdc и hwnd - всё тривиально...
И при чём тут вообще TPanel?? TPanel просто окно-родитель для создаваемого функцией окна дочернего, на TPanel ничего и не рисуется...


> vegarulez   (02.02.11 22:50) [15]
> Пытаюсь передать дескриптор окна -


Функции нужно hdc, а вы ему hwnd суёте... Вот и не работает ничего...)
Даже я таких ошибок давно уже не делаю... :)

var Form1: TForm1; hWndC: HWND; hWndDC: HDC;

...

hWndC:=capCreateCaptureWindowA(...)
hWndDC:=GetDC(hWndC);
Image1.Picture.Bitmap.Width:=Panel1.Width;
Image1.Picture.Bitmap.Height:=Panel1.Height;

...

BitBlt(Image1.Picture.Bitmap.Canvas.Handle, 0, 0, Panel1.Width, Panel1.Height, hWndDC, 0, 0, SRCCOPY);
Image1.Repaint;

...

ReleaseDC(hWndC, hWndDC);


А делать hWndC:=0; имхо неправильно... Вообще я б переделал весь код немного... Да и сохраняет пусть в png, jpg - прошлый век... :)


 
RWolf ©   (2011-02-11 10:51) [27]


> Студент   (10.02.11 23:16) [26]

сохранять картинку с вебкамеры в PNG неразумно, он не для этого предназначен. Lossless форматы плохо сжимают фотографии.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2011.05.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.004 c
15-1297114175
Юрий
2011-02-08 00:29
2011.05.22
С днем рождения ! 8 февраля 2011 вторник


2-1297184901
Студент
2011-02-08 20:08
2011.05.22
Пытался сравнить переменную с функцией изменяющей её значение :(


2-1297692086
Stringgrid
2011-02-14 17:01
2011.05.22
drag&amp;drop в stringgrid


8-1212054041
Дмитрий Белькевич
2008-05-29 13:40
2011.05.22
Упаковка avi


6-1236800865
Дмитрий Белькевич
2009-03-11 22:47
2011.05.22
Не меняется порт в TIdSyslogServer (или скорее TIdUDPServer)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский