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

Вниз

Как ускорить снятие скриншота, Ассемблерная вставка   Найти похожие ветки 

 
Вова   (2013-08-21 17:48) [80]

все же по идее должно быть так....но на боевых данных вчера так не работало....

Procedure TScreenShot.CopyScreenScanLine(var tbmpDest: Tbitmap; Coord: TCoord);
var
 LineLength,SkipLine,i: integer;
 Destination, Start, last: pInteger;
begin
 WaitForSingleObject(MyMutex, INFINITE);
 if (fNumberOfShot = 0) or (tbmpDest.Height < 2) then
   exit;
//y*LineLength+x*PixelSize
   Start := fScreen.ScanLine[(fScreen.Height - 1) - Coord.y1work];
   inc(Start, Coord.x1work);
   Destination := tbmpDest.ScanLine[(tbmpDest.Height - 1)];
   last        := tbmpDest.ScanLine[0];
   LineLength  := tbmpDest.Width;
   SkipLine    := fScreen.Width - tbmpDest.Width;
   //inc(last, tbmpDest.Width);
   LockConvertBmpToRGBColorMapM2(Start, Destination, last,LineLength,SkipLine);
 ReleaseMutex(MyMutex);
end;


 
Sha ©   (2013-08-21 17:50) [81]

Разумеется, не дает. Но красота - страшная сила!

Замени ленч на каунт в объявлении процедуры - и локальная переменная будет не нужна.


 
Вова   (2013-08-21 17:57) [82]

как так не нужна, мне же ее нужно в цикле восстанавливать к прежнему значению, если я его затру, к чему же я его буду восстанавливать?


 
Вова   (2013-08-21 21:49) [83]

Start := fScreen.ScanLine[Coord.y2work];
   inc(Start, Coord.x1work);


короче работает тока так.... а так не работает....Start := fScreen.ScanLine[(fScreen.Height - 1) - Coord.y1work]; где логика......


 
Sha ©   (2013-08-21 22:29) [84]

> мне же ее нужно в цикле восстанавливать к прежнему значению

Ах, да, конечно. Это я съел что-нибудь.



> где логика......

Действительно. Потерял, наверное.


 
Sapersky   (2013-08-22 00:15) [85]

Проверил - обычный BitBlt быстрее копирования через Move и совсем немного уступает варианту с SSE (зато без ограничений по выравниванию и размеру).


 
Вова   (2013-08-22 07:38) [86]

да но последний scanline быстрее SSE )


 
Вова   (2013-08-22 14:23) [87]

вооот, а если вместо PInteger сделать pInt64, то скорость вырастет еще на треть. ток надо чтобы битмап имел четное количество пикселей.


 
Sha ©   (2013-08-22 14:42) [88]

разверни цикл, Люк


 
Вова   (2013-08-22 15:21) [89]


> разверни цикл, Люк


это я так и не понял как делается (


 
Sha ©   (2013-08-22 15:36) [90]

теорию сам погугли, а пример могу дать:

http://guildalfa.ru/alsha/node/22


 
Вова   (2013-08-29 01:06) [91]

тысяча чертей, почему у меня верхняя строка целевого битмапа пустая? я уже все глаза сломал не могу понять (

function CopyRect(ppixel,ppixelDest,last: pInt64;
 Lenght, SkipLine: integer): Boolean;
var
 count: integer;
begin
 count := Lenght;
 repeat
   repeat
     ppixelDest^ := ppixel^;
     inc(ppixel);
     inc(ppixelDest);
     dec(count);
   until count = 0;
   count := Lenght;
   inc(ppixel, SkipLine)
 until ppixelDest = last;
end;

function CalcLenght(EndS, StartS: integer): integer;
begin
 result := EndS - StartS;
end;

Procedure TScreenShot.CopyScreenScanLine(var tbmpDest: Tbitmap; Coord: TCoord);
var
 LineLength, SkipLine, i: integer;
 Destination, Start, last: pInt64;
begin

 tbmpDest.Width  := Coord.x2work - Coord.x1work + 1;
 tbmpDest.Height := Coord.y2work - Coord.y1work + 1;

 if Coord.x2work = 0 then
 begin
   tbmpDest.Width := screen.Width;
   Coord.x2work   := screen.Width - 1
 end;

 if Coord.y2work = 0 then
 begin
   tbmpDest.Height := screen.Height;
   Coord.y2work    := screen.Height - 1;
 end;

 if (tbmpDest.Width div 2) <> (tbmpDest.Width / 2) then
 // строка битмапа должна быть четной
   if tbmpDest.Width = screen.Width then
     tbmpDest.Width := tbmpDest.Width - 1
   else
     tbmpDest.Width := tbmpDest.Width + 1;

 WaitForSingleObject(MyMutex, INFINITE);
 if (fNumberOfShot = 0) or (tbmpDest.Height < 2) then
   exit;

 Start := fScreen.ScanLine[Coord.y2work];
 inc(Start, Coord.x1work div 2);
 Destination := tbmpDest.ScanLine[(tbmpDest.Height - 1)];
 last := tbmpDest.ScanLine[0];
 LineLength := tbmpDest.Width div 2;
 SkipLine := CalcLenght(fScreen.Width, tbmpDest.Width) div 2;

 CopyRect(Start, Destination, last, LineLength, SkipLine);
 ReleaseMutex(MyMutex);
end;


 
Sha ©   (2013-08-29 09:42) [92]

потому что строка, для которой ppixelDest=last, не копируется


 
Вова   (2013-08-30 01:35) [93]

логично, но вопрос как раз в том, почему.


 
Sha ©   (2013-08-30 10:02) [94]

Для того, чтобы скопировать в цикле элементы
с индесами от N-1 до 0, необходимо выйти из цикла
либо после копирования элемента, имеющего нулевой индекс,
либо перед копированием элемента, имеющего отрицательный индекс.


 
Вова   (2013-08-30 13:20) [95]

правильный ответ: Потому что в результате того, что у того кто разрабатывал всю эту архитектуру были не все дома, то tbmpDest.ScanLine[0]; указывает не на конец битмапа, а на конец последней строки(который находится в крайней правой точке картинки), как и любой сканлайн указывает на конец строки битмапа , переданной в параметре, в памяти.


 
Вова   (2013-08-30 13:30) [96]

и таким образом получается, что битмап в памяти не перевернут вообще. Перевернут обход по пикселям. Т.е. если идти по возрастанию, то обход нужно начинать в правом нижнем углу.


 
Вова   (2013-08-30 13:58) [97]

тваюмашу, неугадал (


 
Sapersky   (2013-08-30 14:05) [98]

Ну а что ты хотел - во всех хелпах написано, что на начало, все используют, у всех работает, а тут у Вовы ВНЕЗАПНО на конец...

procedure CopyPart32(Src, Dst : TBitmap; OffsX, OffsY : Integer;
                    Inverted : Boolean = True);
Var y : Integer;
   ps, pd : PDWord;
begin
If Inverted then begin
 ps := Src.ScanLine[0]; // последняя строка
 Dec(ps, Src.Width * (OffsY + Dst.Height));
   // битмап перевёрнут, отступаем СНИЗУ на OffsY + Height
end else begin
 ps := Src.ScanLine[Src.Height-1]; // первая строка
 Inc(ps, Src.Width * OffsY);
end;
Inc(ps, OffsX);
pd := Dst.ScanLine[Dst.Height-1]; // первая строка

For y:=0 to Dst.Height-1 do begin
 Move(ps^, pd^, Dst.Width * 4);
 Inc(ps, Src.Width); Inc(pd, Dst.Width);
end;
end;

Inverted = True - битмапы перевёрнуты, режим по умолчанию.
Inverted = False - битмапы с отрицательной высотой, не перевёрнутые. Это таки работает, но до сканлайна не доходит, что битмап "нормальный", поэтому нужно брать начало (Src.ScanLine[Src.Height-1]) и дальше считать все смещения самостоятельно.


 
Вова   (2013-09-02 01:35) [99]


> Вовы ВНЕЗАПНО на конец...


а все потому, что нет ни одной понятной картинки

опщем, да нужно было просто inc от scanline[0] в конец строки сделать. И также меня вдруг осенило как работать с перевернутым массивом так как будто он не перевернут. И то что Ша тут партизанит, не думаю, что это чему то меня учит, просто я потратил кучу времени чтобы понять то что мог понять с одного поста ответа тут ) удивительное отношение на форуме, я уже тут полгода со всем этим сношаюсь, а ко мне относятся так как будто я студент пришел кусовую нахаляву списать )

Вообщем вроде все починил, 3.3 миллисекунды на 1920 на 1080 шарашит, но че то на win7 работает, а на XP нет...нада будет смотреть опять (


 
Вова   (2013-09-02 01:42) [100]

хотя в начале Ша конечно меня нереально продвинул ) сам бы я до такого не дошел. Спал бы спокойно )) Сейчас скорость программы даже создает определенные трудности, она работает так быстро, что приходится паузы ставить, что бы инфа успевала обновляться ) но зато есть задел на бОльшие объемы данных. Хотя второй фильтр все еще медленней 170 милисекунд, но уже его в 2 раза убыстрил )


 
ProgRAMmer Dimonych ©   (2013-09-02 21:19) [101]

> И также меня вдруг осенило как работать с перевернутым массивом
> так как будто он не перевернут. И то что Ша тут партизанит,
> не думаю, что это чему то меня учит, просто я потратил
> кучу времени чтобы понять то что мог понять с одного поста
> ответа тут )

А вот это и есть самый лучший способ действительно разобраться в вопросе: дойти самому, а не получить готовое на блюдечке :)



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

Текущий архив: 2014.06.29;
Скачать: CL | DM;

Наверх




Память: 0.65 MB
Время: 0.015 c
1-1326095552
solomon
2012-01-09 11:52
2014.06.29
Странность при работе с Record


2-1376482907
Вова
2013-08-14 16:21
2014.06.29
Как ускорить снятие скриншота, Ассемблерная вставка


15-1386762986
azlk2141
2013-12-11 15:56
2014.06.29
выбор мобильного оператора


15-1386866320
Абориген
2013-12-12 20:38
2014.06.29
Назвать DupeString() по-другому?


2-1377774807
delphi.coder
2013-08-29 15:13
2014.06.29
работа с объктом TFieldDataLink