Форум: "Начинающим";
Текущий архив: 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