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

Вниз

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

 
Вова   (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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.63 MB
Время: 0.006 c
2-1377673167
санек
2013-08-28 10:59
2014.06.29
Кодировка dbf файла


2-1365433789
Максим
2013-04-08 19:09
2014.06.29
Создаеие бд MS access во время выполнения без ОБЯЗАТЕЛЬНЫХ ПОЛЕЙ


2-1373372132
Разведка
2013-07-09 16:15
2014.06.29
не преодолимый глюк


15-1387103920
Cobalt
2013-12-15 14:38
2014.06.29
copy-on-write 8-bit строки


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





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский