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

Поиск:

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


Опытный
**


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

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



Ребята, мне надо инвертировать часть изображения. Какие есть пути решения пограмотней?


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

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

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

---

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


Законченный романтик
***


Профиль
Группа: Завсегдатай
Сообщений: 1784
Регистрация: 11.3.2009
Где: Земля

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



Если просто прямоугольником от координаты (x1, y1) до (x2, y2), то можно скопировать часть изображения на отдельный битмап, и там уже его инвертировать, а решений есть много одно из них вы с легкостью найдёте в DRKB или Delphiworld


--------------------
"И твоя голова всегда в ответе за то куда сядет твой зад..."

"Я студент - скажите с какого я ВУЗа..."

 smile  smile  smile 
PM MAIL   Вверх
PsiMagistr
Дата 23.6.2010, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Спасибо. Это на поверхности конечно. А без создания отдельного BitMap?


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

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

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

---

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


Опытный
**


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

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



пробегаешь по канвасу (если оно есть) или по пикселям битмапа (если он есть) сканлайном, достаешь каналы пикселя (GetRvalue() например, у сканлайна они уже готовые), отнимаешь их от 255 и записываешь обратно


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


Эксперт
****


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

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



Зачем сканлайн? Это долго.
Да и смысл изобретать велосипед, когда всё уже готово.
И да, можно без второго битмапа. И всего в одну строку.

Допустим, нужно инвертировать прямоугольную область x100:y50, шириной 200:100
Код
  BitBlt(bmp.Canvas.Handle, 100, 50, 200, 100, bmp.Canvas.Handle, 100, 50, DSTINVERT);
DSTINVERT говорит, что мы просто хотим инвертировать фрагмент исходного изображения.
PM MAIL   Вверх
Frees
Дата 23.6.2010, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2233
Регистрация: 2.12.2005
Где: Екатеринбург

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



Код

var
  r: TRect;
begin
  Image1.Picture.Bitmap.Canvas.CopyMode := cmDstInvert;
  r := Rect(10,10,100,100);
  Image1.Picture.Bitmap.Canvas.CopyRect(r, Image1.Picture.Bitmap.Canvas, r);
  Image1.Picture.Bitmap.Canvas.CopyMode := cmSrcCopy;


Это сообщение отредактировал(а) Frees - 23.6.2010, 12:35


--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
PsiMagistr
Дата 23.6.2010, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Спасибо. Но пока не вышло. Имею Image на форме. При нажатии на кнопку должен инвертироваться прямоугольник.

Координаты верхней точки прямоугольника 0, 0.

ширина 128, высота 83.

Пробовал 

Код

BitBlt(Im.Picture.Bitmap.Canvas.Handle, 0, 0, 128, 83, Im.Picture.Bitmap.Canvas.Handle, 128, 83, DSTINVERT);


Ноль внимания.

Добавлено через 1 минуту и 9 секунд
Frees,  спасибо, сейчас еще ваш пример попробую.

Добавлено через 6 минут и 26 секунд
Frees,  Ваше работает однако. 

А что за метод: CopyMode? И что такое  cmSrcCopy; 


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

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

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

---

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


Эксперт
****


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

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



Цитата(PsiMagistr @  23.6.2010,  12:42 Найти цитируемый пост)
Ноль внимания.
Правильно. Код только инвертирует изображение. Но не рисует его.
В случае с имаджем, нужно его обновить.
Код
  BitBlt(Im.Picture.Bitmap.Canvas.Handle, 0, 0, 128, 83, Im.Picture.Bitmap.Canvas.Handle, 0, 0, DSTINVERT);
  Im.Refresh;


Цитата(PsiMagistr @  23.6.2010,  12:42 Найти цитируемый пост)
А что за метод: CopyMode? И что такое  cmSrcCopy; 
CopyMode - последний параметр в BitBlt.
cmDstInvert в CopyRect - то же самое, что и DSTINVERT в BitBlt.
PM MAIL   Вверх
PsiMagistr
Дата 23.6.2010, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Snowy,  Сенкс, воспользовался BitBlit.


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

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

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

---

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


Опытный
**


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

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



Snowy
Цитата

Зачем сканлайн? Это долго.

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


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


Опытный
**


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

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



AntonN, Если сканлайнить то надо строки изображения циклом проходить, как я понял...


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

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

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

---

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


Опытный
**


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

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



Заметил любопытнейшую вещь.

Если ДО вызова функции  BitBlt выполнить в Image загрузку изображения из какого либо файла, действие функции отображается несмотря на отсутствие refresh.

То есть

Код

BitBlt(Im.Picture.Bitmap.Canvas.Handle, 0, 0, 128, 83, Im.Picture.Bitmap.Canvas.Handle, 0, 0, DSTINVERT);
Im.Refresh;


Визуально аналогично следующему:

Код

Im1.Picture.LoadFromFile(ExtractFilePath(Application.ExeName)+ 'Proba.bmp');
BitBlt(Im.Picture.Bitmap.Canvas.Handle, 0, 0, 128, 83, Im.Picture.Bitmap.Canvas.Handle, 0, 0, DSTINVERT);


Как и почему так получается не разобрался. Да картинка вроде обновляется из за загрузки. Но она же обновляется до операции BitBlt



Это сообщение отредактировал(а) PsiMagistr - 23.6.2010, 16:30


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

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

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

---

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


Опытный
**


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

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



Скорее всего оно перерисовывается сообщением, которое обрабатывается после того как исполнится весь код и будет выполняться обработчик сообщений.


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


Опытный
**


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

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



Mikel,  Шут его знает дружище, вот например погляди:

Код

procedure TfrmGame.ImgMapClick(Sender: TObject);
 var R1,R2:TRect; //Области копирования.
begin
 ImgMap.Picture.LoadFromFile(ExtractFilePath(Application.ExeName)+'map.bmp'); //Грузим файл.
 ImgMap.Canvas.Brush.Style := bsClear; //Очищаем кисть
 ImgMap.Canvas.Pen.Color := clblue;
 ImgMap.Canvas.Rectangle(Lt1,Tp1,Lt2,Tp2);
 R1:=Rect(0,0,128,83); //Определяем область куда хотим копировать.
 R2:= Rect(Lt1,Tp1,Lt2,Tp2);  //Определяем область откуда хотим копировать.
 ImgLocation.Canvas.CopyRect(R1, ImgMap.Canvas, R2); //Рисуем нечто на изображении. А вот если здесь заккоментировать, для BitBlit понадобится рефреш в конце.
 BitBlt(ImgLocation.Picture.Bitmap.Canvas.Handle, 0, 0, 128, 83, ImgMap.Picture.Bitmap.Canvas.Handle, LT1, TP1, DSTINVERT); 

//BitBlt идет вообще последней командой. Однако рефрешить изображение не надо. Ибо мы рисовали на нем. 
end;





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

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

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

---

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


Опытный
**


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

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



Просто пытаюсь понятькак работает функция. 

Все интересней и интересней. Есть два Image. ImgMap, ImLocation. В ImgLocation есть некое стартовое изображение по умолчанию.  Мы берем ImMap, и копируем оттуда кусочек в ImgLocation. Копировать надо с инвертированием.

Итак:

Код

procedure TfrmGame.ImgMapClick(Sender: TObject);
 var R1,R2:TRect; //Области копирования.
begin
 ImgMap.Picture.LoadFromFile(ExtractFilePath(Application.ExeName)+'map.bmp'); //Грузим файл.
 ImgMap.Canvas.Brush.Style := bsClear; //Очищаем кисть
 ImgMap.Canvas.Pen.Color := clblue;
 ImgMap.Canvas.Rectangle(Lt1,Tp1,Lt2,Tp2);
 R1:=Rect(0,0,128,83); //Определяем область куда хотим копировать.
 R2:= Rect(Lt1,Tp1,Lt2,Tp2);  //Определяем область откуда хотим копировать.
 ImgLocation.Picture.Bitmap.Canvas.CopyMode := cmDstInvert; //Если убрать эту строку, само копирование нужных участков происходит нормально, но естесственно без инвертирования. Если добавить эту строку, будет постоянно инвертироваться (туда-сюда), не меняясь, стартовое изображение.
 ImgLocation.Canvas.CopyRect(R1, ImgMap.Canvas, R2);
 end;

//В причинах не разобрался. Но получается, что сам режим cmInvert мешает правильному копированию участка. Как такое быть может?





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


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

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

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

---

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


Опытный
**


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

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



Спасибо большое. Уже ассемблерные вставки появились.  smile  


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

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

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

---

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


Опытный
**


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

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



Ребята, все. Уф-ф-ф. Спасибо всем. Причина: У меня картинка не очень чистая была. На глаз нипочем не заметно. А при инвертировании - пятна моментом.

Добавлено через 2 минуты и 39 секунд
Ребята, все. Уф-ф-ф. Спасибо всем. Причина: У меня картинка не очень чистая была. На глаз нипочем не заметно. А при инвертировании - пятна моментом.


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

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

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

---

"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
PM MAIL   Вверх
Страницы: (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.1386 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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