Модераторы: Snowy, MetalFan, bems, Poseidon

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Инвертировать часть изображения 
:(
    Опции темы
Mikel
Дата 24.6.2010, 08:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 882
Регистрация: 30.3.2002
Где: Саратов

Репутация: нет
Всего: 2



Ну да, скорее всего если вместо ImgLocation.Canvas.CopyRect(R1, ImgMap.Canvas, R2); будешь работать не с канвами самого image, а с bitmap.canvas, то не перерисуется smile а перерисовывается при любом изменении посредством GDI каким-н сообщением CM_INVALIDATE.
Работает- оставь и не трогай  smile 


--------------------
...so remember, it's better to burn out than to fade away
PM MAIL ICQ   Вверх
PsiMagistr
Дата 24.6.2010, 08:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009

Репутация: 1
Всего: 1



Гм. Ничего не понял. Как инверт-режим может мешать правильному копированию участка?

Это сообщение отредактировал(а) PsiMagistr - 24.6.2010, 09:00


--------------------
"Арфы нет? Возьмите бубен!

Ребята, будем жить!"

 (с) "В бой идут одни старики"

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
PsiMagistr
Дата 24.6.2010, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009

Репутация: 1
Всего: 1



Не поленюсь - выложу исходный кусок.



Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  ___.rar 97,71 Kb


--------------------
"Арфы нет? Возьмите бубен!

Ребята, будем жить!"

 (с) "В бой идут одни старики"

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
PsiMagistr
Дата 24.6.2010, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009

Репутация: 1
Всего: 1



Как будто точно от режима зависит. странно.

При попытке просто копировать участок изображения в другой Image

Код

BitBlt(ImgLocation.Picture.Bitmap.Canvas.Handle, 0,0,128,83, ImgMap.Picture.Bitmap.Canvas.Handle, Lt1,Tp1, SrcCopy);
ImgLocation.Refresh;



Как по маслу.

При попытке изменить режим на DstInvert, чтобы :

Код

BitBlt(ImgLocation.Picture.Bitmap.Canvas.Handle, 0,0,128,83, ImgMap.Picture.Bitmap.Canvas.Handle, Lt1,Tp1, DstInvert);
ImgLocation.Refresh;


Не происходит копирования участка.


--------------------
"Арфы нет? Возьмите бубен!

Ребята, будем жить!"

 (с) "В бой идут одни старики"

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
AntonN
Дата 24.6.2010, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 3
Всего: 18



Код

procedure InvertRect_GDI(BT:Tbitmap; x,y:integer; width,height:word);
const
 MaxPixelCountA = MaxInt div SizeOf(TRGBQuad);
type
 PRGBAArray = ^TRGBAArray;
 TRGBAArray = array[0..MaxPixelCountA-1] of TRGBQuad;
var xTo,sx,YTo,sy,dstw,dsth: integer;
   i,ii:integer; RSource:PRGBAArray;
begin
 dstw:=bt.width;
 dsth:=BT.height;
 XTo:=x+Width-1; YTo:=y+height-1;
 if (y>=dstH) or (x>=dstW) or (YTo<0) or (XTo<0) then exit;
 sx:=Width; sy:=height;
 if X<0 then begin
     inc(sx,X);
     x:=0;
 end;
 if Y<0 then begin
     inc(sy,Y);
     y:=0;
 end;
 if XTo>=dstw then dec(sx,XTo-dstw+1);
 if YTo>=dsth then dec(sy,YTo-dsth+1);
 if (sx<=0) or (sy<=0) then exit;
 BT.PixelFormat:=pf32bit;

   for i:=0 to sy-1 do begin
     RSource:=BT.ScanLine[i+y];
     for ii:=0 to sx-1 do begin
       RSource[x+ii].rgbRed:=255-RSource[x+ii].rgbRed;
       RSource[x+ii].rgbGreen:=255-RSource[x+ii].rgbGreen;
       RSource[x+ii].rgbBlue:=255-RSource[x+ii].rgbBlue;
     end;
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  InvertRect_GDI(Image1.Picture.Bitmap,164,6,250,350);
  Image1.Invalidate;
end;



--------------------
user posted image
PM MAIL WWW   Вверх
PsiMagistr
Дата 24.6.2010, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009

Репутация: 1
Всего: 1



Спасибо большое. Только долго.




--------------------
"Арфы нет? Возьмите бубен!

Ребята, будем жить!"

 (с) "В бой идут одни старики"

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
Snowy
Дата 24.6.2010, 11:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 31
Всего: 484



Цитата(PsiMagistr @  23.6.2010,  16:30 Найти цитируемый пост)
Если ДО вызова функции  BitBlt выполнить в Image загрузку изображения из какого либо файла, действие функции отображается несмотря на отсутствие refresh.
Так рефреш выполняет процедура зарузки.
Сам рефреш не перерисовывает, а только даёт запрос в очередь сообщений, что нужно перерисовать.
Он отработает тогда, когда приложением будет получено сообщение на перерисовку.
А оно не будет получено, пока мы не отпустим тред.
Если между коммандами вставить Application.ProcessMessages, то он выполнит очередь сообщений и только потом будет инфертирование.
Как только мы закончим, очередь сообщений будет обработана, запрос отрисовки будет выполнен.

Цитата(PsiMagistr @  24.6.2010,  11:33 Найти цитируемый пост)
Только долго.
Ну так я сразу так и сказал...
PM MAIL   Вверх
AntonN
Дата 24.6.2010, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 3
Всего: 18



PsiMagistr
Цитата

Спасибо большое. Только долго.

Долго? для чего долго?

Добавлено через 2 минуты и 11 секунд
1000 инвертирований за 0,6 секунды областей 250*250 - это долго?

Добавлено через 5 минут и 7 секунд
небольшое изменение...
Код

for i:=0 to sy-1 do begin
     RSource:=BT.ScanLine[i+y];
     for ii:=0 to sx-1 do begin
       ix:=x+ii;
       RSource[ix].rgbRed:=255-RSource[ix].rgbRed;
       RSource[ix].rgbGreen:=255-RSource[ix].rgbGreen;
       RSource[ix].rgbBlue:=255-RSource[ix].rgbBlue;
     end;
   end;


и те же 1000 инвертов улетают за 0,18 секунды, это 5555 операций в секунду? ты ничего с "долго" не перепутал?


--------------------
user posted image
PM MAIL WWW   Вверх
PsiMagistr
Дата 24.6.2010, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009

Репутация: 1
Всего: 1



Не перепутал дружище. Если есть функция инвертирования, то зачем изобретение велосипеда?)


--------------------
"Арфы нет? Возьмите бубен!

Ребята, будем жить!"

 (с) "В бой идут одни старики"

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
AntonN
Дата 24.6.2010, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 3
Всего: 18



Код

procedure TForm1.Button1Click(Sender: TObject);
var Divisor:Int64; T1,T2:Int64; i:integer; TotalTime:Extended;
begin
  Image1.Picture.Bitmap.PixelFormat:=pf32bit;
  if QueryPerformanceFrequency( Divisor ) then begin
     QueryPerformanceCounter(T2);


     for i:=0 to 1001-1 do begin
       InvertRect_GDI(Image1.Picture.Bitmap,0,0,640,480);
       //0,71
     end;

     {for i:=0 to 1001-1 do begin
       BitBlt(Image1.Picture.Bitmap.Canvas.Handle, 0, 0, 640, 480, Image1.Picture.Bitmap.Canvas.Handle, 0, 0, DSTINVERT);
       //0,88
     end; }


     QueryPerformanceCounter(T1);
     TotalTime:=(T1-T2)/Divisor ;
     edit1.text:=floattostr(TotalTime);
   end;

  Image1.Invalidate;
end;

сканлайн оказался быстрее на 20% (глубина цветности дисплея 32 бита). "Долго"...
Это еще без оптимизации до асма, пара xor+add с такой скоростью улетят, что моргнуть не успеем...


--------------------
user posted image
PM MAIL WWW   Вверх
AntonN
Дата 24.6.2010, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 3
Всего: 18



PsiMagistr
я и вжу как она есть, уже второй день не можешь ее победить smile
а потом вдруг тебе понадобится серпия, crayscale, еще что нибудь - тоже готовое будешь искать? smile


--------------------
user posted image
PM MAIL WWW   Вверх
Mikel
Дата 24.6.2010, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 882
Регистрация: 30.3.2002
Где: Саратов

Репутация: нет
Всего: 2



Я не понял что ты хочешь, но попробуй так: )))
Код

 ImgLocation.Picture.Bitmap.Canvas.CopyMode := NOTSRCCOPY;  //Попробуйте заккоментировать строку.
 ImgLocation.Picture.Bitmap.Canvas.CopyRect(R1, ImgMap.Canvas, R2);



--------------------
...so remember, it's better to burn out than to fade away
PM MAIL ICQ   Вверх
AntonN
Дата 24.6.2010, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 3
Всего: 18



С позволения, я еще пофлужу...
Код

function DIBBits(BMP: TBitmap): Pointer;
var Section:TDIBSECTION;
begin
BMP.HandleType:=bmDIB;
GetObject(BMP.Handle,sizeof(TDIBSECTION),@Section);
Result:=Section.dsBm.bmBits;
end;

function ScanLineSize(BMP: TBitmap): Integer;
var Section:TDIBSECTION;
begin
BMP.HandleType:=bmDIB;
GetObject(BMP.Handle,sizeof(TDIBSECTION),@Section);
Result:=((Section.dsBmih.biBitCount * Section.dsBmih.biWidth + 31) shr 3) and $FFFFFFFC;;
end;

procedure InvertRect_GDI_asm(BT:Tbitmap; x,y:integer; width,height:word);
const
 MaxPixelCountA = MaxInt div SizeOf(TRGBQuad);
type
 PRGBAArray = ^TRGBAArray;
 TRGBAArray = array[0..MaxPixelCountA-1] of TRGBQuad;
var xTo,sx,YTo,sy,dstw,dsth: integer;
   i,ii,ix,inc1:integer; RSource:PRGBAArray;  DstBits:DWORD;
begin
 dstw:=bt.width;
 dsth:=BT.height;
 XTo:=x+Width-1; YTo:=y+height-1;
 if (y>=dstH) or (x>=dstW) or (YTo<0) or (XTo<0) then exit;
 sx:=Width; sy:=height;
 if X<0 then begin
     inc(sx,X);
     x:=0;
 end;
 if Y<0 then begin
     inc(sy,Y);
     y:=0;
 end;
 if XTo>=dstw then dec(sx,XTo-dstw+1);
 if YTo>=dsth then dec(sy,YTo-dsth+1);
 if (sx<=0) or (sy<=0) then exit;
 BT.PixelFormat:=pf32bit;
 inc1:=ScanLineSize(BT);
 DstBits:=DWORD( DWORD( DIBBits(BT)) + y*inc1 + x*4 );

  asm
   mov   eax, $FFFFFF
   @outer_loop:
    mov   ecx, sx
    mov   edi, DstBits
    
   @loop:
    xor   [edi], eax
    add   edi, 4
    dec   ecx
    jnz   @loop

   @l1:
    mov   ecx, inc1
    add   DstBits, ecx
    dec   sy
    jnz   @outer_loop
  end;
end;

накидал на скорую руку, выполняется при тех же параметрах из моего предшествующего поста за 0.3 секунды, это чуть больше чем в 2.5 раза быстрее BitBlt()

хотя вероятно где-то есть корявки, удивлен что BitBlt() в этом режиме показывает такие низкие результаты...


--------------------
user posted image
PM MAIL WWW   Вверх
Snowy
Дата 24.6.2010, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 31
Всего: 484



Для точности эксперимента увеличил до 10000 инверсий.
Результат на моем ноуте:
InvertRect_GDI - 40 секунд
BitBlt - 13 секунд
Итог: Битблит в 3 раза быстрее
PM MAIL   Вверх
AntonN
Дата 24.6.2010, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 3
Всего: 18



У меня просто проц не слабый. С последней функцией можешь сравнить? просто интересно


--------------------
user posted image
PM MAIL WWW   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0951 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.