Текущий архив: 2009.08.02;
Скачать: CL | DM;
Вниз
передача TBitmap в другой поток Найти похожие ветки
← →
night_light © (2009-06-08 11:34) [0]Здравствуйте!
Уважаемые мастера Делфи, возникла проблема,
при передаче результата видеозахвата (компонент TVideoGrabber) в другой поток для обработки:
...
var
Form1: TForm1;
calculate: Thread_calculate;
event_capture_enable: TEvent;
start_calculate: TEvent
...
procedure TForm1.FormCreate(Sender: TObject);
begin
...
start_calculate := TEvent.Create(nil, false, false, "");
event_capture_enable:=TEvent.Create(nil,true,true,"");
...
end;
procedure TForm1.TimerStartCaptureTimer(Sender: TObject);
begin
if ( event_capture_enable.WaitFor(0)=wrSignaled ) then
begin
event_capture_enable.ResetEvent;
Video_Calculate.VideoGrabber1.CaptureFrameTo(fc_TBitmap);
end;
end;
procedure TForm1.VideoGrabber1FrameCaptureCompleted(Sender: TObject;
const FrameData: TFrameData; DestType: TFrameCaptureDest;
FileName: String; Success: Boolean);
begin
if Success then
begin
calculate.InBitmap.Assign(FrameData.Bitmap);
calculate.start_calculate.SetEvent;
...
end;
end;
а вот это в другом потоке (и модуле):
...
Thread_calculate = class(TThread)
public
InBitmap: TBitmap;
...
procedure Thread_calculate.Execute;
begin
while True do
begin
start_calculate.WaitFor(infinite);
...
// обработка с участием InBitmap
...
event_capture_enable.SetEvent;
end;
end;
возникает утечка памяти,
если же копировать попиксельно:
procedure TForm1.VideoGrabber1FrameCaptureCompleted(Sender: TObject;
const FrameData: TFrameData; DestType: TFrameCaptureDest;
FileName: String; Success: Boolean);
begin
if Success then
begin
calculate.InBitmap.Assign(FrameData.Bitmap);
for ix := 0 to 575 do
for iy := 0 to 575 do
begin
calculate.InBitmap.Canvas.Pixels[ix, iy] :=
FrameData.Bitmap.Canvas.Pixels[ix, iy];
end;
calculate.start_calculate.SetEvent;
...
end;
end;
то утечки нет, но получается очень долго, 400 мс на копирование одной картинки. Подскажите, пожалуйста, в чём может быть проблема и как устранить утечку?
← →
AIK © (2009-06-08 11:44) [1]Обращайся к тому у кого этот компонент скачал
← →
night_vision (2009-06-08 11:47) [2]Используйте заранее созданный буфер кадров (штук на 10-20-100), выделите память под него, позоздавайте битмапы и т.п.
Один поток ложит в буфер кадр, и передаёт во второй поток только номер. Никаких Assign-ов!
PS: Пользуйтесь тегом CODE :)
← →
night_light © (2009-06-08 12:02) [3]>night_vision
>...
Спасибо большое! В какой форме лучше создать этот буфер? В виде массива Bitmap-ов? Или есть особый тип данных?
И ещё, копировать вы предлагаете так же, попиксельно?
И ещё, почему не работает с assign? Хочется понять.
> PS: Пользуйтесь тегом CODE
учту, новичок здесь
← →
night_vision (2009-06-08 12:56) [4]
> night_light © (08.06.09 12:02) [3]
> В какой форме лучше создать этот буфер? В виде массива Bitmap-ов?
В какой Вам будет угодно - можно и массив :)
> И ещё, копировать вы предлагаете так же, попиксельно?
Я предлагаю не копировать вообще. Не совсем понятно куда помещают картинку в этой строчкеVideo_Calculate.VideoGrabber1.CaptureFrameTo(fc_TBitmap);
fc_TBitmap это что ? TBitmap или что-то другое ?
Если битмап тоInBitmap: TBitmap;
не нужен вообще я так понимаю. Если уж очень хочеться копировать, то пользуйтесьScanline
- работает на порядок быстрееPixels
:)
Кстати - а что это за картинка странная размером 575*575 ? Это кроп из 720*576 ?
> И ещё, почему не работает с assign? Хочется понять.
Так посмотрите в исходникахTBitmap
. Мне сейчас лень запускать делфай, если чесно ;)
← →
night_light © (2009-06-08 13:13) [5]> Не совсем понятно куда помещают картинку в этой строчке
> Video_Calculate.VideoGrabber1.CaptureFrameTo(fc_TBitmap);
> fc_TBitmap это что ? TBitmap или что-то другое ?
fc_TBitmap - это формат, в который производится видеозахват, или назначение захватанной картинки, возможны варианты - в файл BMP, в файл JPEG и в TBitmap (fc_TBitmap).
Сам захват происходит как-бы в другом потоке, ф-ияCaptureFrameTo
только запускает видеозахват и сразу же возвращает управление. Результат возвращается в событие:procedure TForm1.VideoGrabber1FrameCaptureCompleted(Sender: TObject;
const FrameData: TFrameData; DestType: TFrameCaptureDest;
FileName: String; Success: Boolean);
с результатом захвата в параметреTFrameData
Насчёт копирования, возможно, придётся поворачивать картинку на 90 градусов. Как я понимаю, здесьscanline
не поможет.
Картинка - просто обрезка из 752x582, чтобы были поля, т.е. чтобы можно было в пределах нескольких пикселей двигать картинку для коррекции смещения.
← →
night_light © (2009-06-08 13:15) [6]TVideoGrabber.CaptureFrameTo
Captures the next video frame.
Delphi Syntax
function CaptureFrameTo(Dest: TFrameCaptureDest; FileName: string): boolean; overload;
function CaptureFrameTo(Dest: TFrameCaptureDest): boolean; overload;
C++ Syntax
bool __fastcall CaptureFrameTo(TFrameCaptureDest Dest, AnsiString FileName)
bool __fastcall CaptureFrameTo(TFrameCaptureDest Dest)
Description
Captures the next video frame to a TBitmap, a BMP file or a JPEG file, according to the Dest parameter. The frame grabber must be enabled to use this function.
The video frame is returned asynchronously by the OnFrameCaptureCompleted event.
When capturing a BMP or JPEG image to a file (Dest = fc_BmpFile or Dest = fc_JpegFile) :
- if file name is passed as 2nd parameter (1st syntax), this file name will be used to save the frame,
- it no file name is passed (2nd syntax), a file name will be generated automatically in the StoragePath directory according to AutoFileName and AutoFilePrefix.
Страницы: 1 вся ветка
Текущий архив: 2009.08.02;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.012 c