Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.05.22;
Скачать: CL | DM;

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.01 c
15-1296566174
oxffff
2011-02-01 16:16
2011.05.22
Есть интересная задача


1-1254725450
Aleks
2009-10-05 10:50
2011.05.22
Как вывести а потом стереть текст на канве Image?


15-1297153035
И. Павел
2011-02-08 11:17
2011.05.22
Отправка писем на русском языке


8-1212481376
leonidus
2008-06-03 12:22
2011.05.22
Ошибка "JPEG error #41"


15-1297253986
Доменик
2011-02-09 15:19
2011.05.22
Web разработка