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

Вниз

[GDI] Полупрозрачная надпись   Найти похожие ветки 

 
Kerk ©   (2005-10-11 19:59) [0]

сабж. как сделать?


 
Kind ©   (2005-10-11 20:15) [1]

Выводить текст во временный битмап а потом битмап AlphaBlend`ом рисовать.


 
Antonn ©   (2005-10-12 05:34) [2]

Kerk ©   (11.10.05 19:59)
можно с использованием scanline"а


 
Antonn ©   (2005-10-12 07:25) [3]

Kerk ©   (11.10.05 19:59)
я на мыло скинул пример


 
Kerk ©   (2005-10-12 20:35) [4]


> Antonn

Спасибо :)


 
OSokin ©   (2005-10-15 19:23) [5]

SetBkMode(DC, TRANSPARENT)


 
Antonn ©   (2005-10-15 19:25) [6]

OSokin ©   (15.10.05 19:23) [5]
этож только фон прозрачный, а я так понял, что нужно было с прозрачностью букв(в процентах) и прозрачным фоном.


 
WondeRu ©   (2005-10-19 17:37) [7]

надо GDI+ использовать и будет в жизни счастье


 
Antonn ©   (2005-10-19 18:12) [8]

WondeRu ©   (19.10.05 17:37) [7]
надо GDI+ использовать и будет в жизни счастье

можно и без GDI+, средствами GDI.
может в кладовку модуль выложить?..


 
Zeqfreed ©   (2005-10-19 21:51) [9]

Antonn ©   (19.10.05 18:12) [8]
Отчего ж не выложить, конечно выкладывай :)


 
Kerk ©   (2005-10-20 01:07) [10]

WondeRu ©   (19.10.05 17:37) [7]
GDI+


В топку.


 
Kerk ©   (2005-10-20 01:07) [11]

Antonn ©   (19.10.05 18:12) [8]
может в кладовку модуль выложить?..


Конечно выкладывай :)


 
Antonn ©   (2005-10-20 03:20) [12]

выложил, модератор проверяет:)

там, кстати, не только прозрачный текст, но и под углом. Да и другие функции есть.


 
Kerk ©   (2005-10-22 11:13) [13]

Собственно, вот:
http://kladovka.net.ru/index.cgi?pid=list&rid=252
:)


 
Fenik ©   (2005-10-23 17:49) [14]

> http://kladovka.net.ru/index.cgi?pid=list&rid=252

Хоть бы маленько оптимизировал..
Про оформление кода ваще молчу :))


 
Antonn ©   (2005-10-23 18:14) [15]

Fenik ©   (23.10.05 17:49) [14]
Хоть бы маленько оптимизировал..

хоть чего оптимизировать? :)
обращение к width,height не такие и ресурсоемкие. куча проверок - для "безопасности" выполнения, чтоб без всяких АВ (я на этом помешан:)).


> Про оформление кода ваще молчу :))

Нет там оформления:) Я то все там понимаю, никого не заставляю ворошить его.
Вот ниче больше не положу:)


 
Fenik ©   (2005-10-23 19:35) [16]

Смотрим первую процедуру CopyTransparentBitmap:

        _r:= trunc(RowOut[x+_x].rgbtRed+(((RowIn[x].rgbtRed-RowOut[x+_x].rgbtRed)/100)*_transparent));

Почему бы в начале не завести такую вот переменную

D: Double;
...
D := _transparent / 100;


которая избавила бы нас от трех лишних делений при каждой итерации:

        _r:= trunc(RowOut[x+_x].rgbtRed+(RowIn[x].rgbtRed-RowOut[x+_x].rgbtRed) * D);

Потом лишние обращения к памяти через указатели тоже нехорошо. Ещё сложение можно вынести за перделы Trunc, чтобы оно было целочисленным. Получаем:

  OutRed := RowOut[x + _x].rgbtRed;
  InRed := RowIn[x].rgbtRed;
  _r := OutRed + Trunc((InRed - OutRed) * D);


Смотрим дальше:

       if _r>255 then _r:=255; if _r<0 then _r:=0;

Если _r > 255, то проверка на < 0 зачем-то тоже производится. Нафига?
Надо так:


  if _r > 255 then _r := 255
    else if _r < 0 then _r := 0;


Подытожим:

  x2 := x_corS + _x; // Избавление ещё от 6-и лишних сложений типа x + _x
  for x := x_corS to _B_in.Width - 1 - x_cor do begin
    with RowIn[x] do begin
      InBlue  := rgbtBlue;
      InGreen := rgbtGreen;
      InRed   := rgbtRed;
    end;
    if not ((InRed = rc1) and (InGreen = gc1) and (InBlue = bc1)) then
    begin
      OutRed := RowOut[x2].rgbtRed;
      _r := OutRed + Trunc((InRed - OutRed) * D);
      if _r > 255 then _r := 255
        else if _r < 0 then _r:=0;

      OutGreen := RowOut[x2].Green;
      _g := OutGreen + Trunc((InGreen - OutGreen) * D);
      if _g > 255 then _g := 255
        else if _g < 0 then _g := 0;

      OutBlue := RowOut[x2].rgbtBlue;
      _r := OutBlue + Trunc((InBlue - OutBlue) * D);
      if _b > 255 then _b := 255
        else if _b < 0 then _b := 0;

      RowOut[x2].rgbtRed   := _r;
      RowOut[x2].rgbtGreen := _g;
      RowOut[x2].rgbtBlue  := _b;
    end;
    Inc(x2);
  end;


Чувствуешь разницу? :)

---------
Ещё к примеру PrepareBitmapBluuum:

  _r:=trunc(_r/sqr(_persent*2+1));
  _g:=trunc(_g/sqr(_persent*2+1));
  _b:=trunc(_b/sqr(_persent*2+1));


Здесь опять тоже самое. Главное правило оптимизации: выноси за пределы цикла всё, что можно вынести:

var D: Double;
begin
  D := 1/sqr(_persent*2+1);
  ...
  ...
  _r := Trunc(_r * D);
  _g := Trunc(_g * D);
  _b := Trunc(_b * D);


D := 1/sqr.. сделано для того, чтобы в цикле использовать умножение вместо деления, т.к. умножение быстрее.
И так далее и тому подобное...

----
ЗЫ: Подчеркивания _перед _именами _перемнных читаются просто ужасно!


 
Antonn ©   (2005-10-23 19:53) [17]

Fenik ©   (23.10.05 19:35) [16]
Если _r > 255, то проверка на < 0 зачем-то тоже производится. Нафига?

ага, тут я точно пролетел:)

> Чувствуешь разницу? :)

визуально - чувствую, программно - не-а:)
замерял через QueryPerformanceCounter, среднее от 200 копирований изображений 128*128. Разницы практически нет(т.е. она есть, но "скачет" от одного варианта, к другому, от теста к тесту). Может если отключить оптимизацию, то разница и будет. Я потому и бросил оптимизировать да ассемблерными вставками заменять, что все одно. Да и не такие уж тормоза, чтобы придераться к скорости выполнения:)


> ЗЫ: Подчеркивания _перед _именами _перемнных читаются
> просто ужасно!

_ну _не _знаю, мне наоборот проще такие выявлять, я так выделяю наиболее важные, _привычка:)


 
Fenik ©   (2005-10-23 20:07) [18]

> Antonn ©  (23.10.05 19:53) [17]
> визуально - чувствую, программно - не-а:)


Надо изображения побольше брать, а компутер послабее.

Кстати, ещё можно избавиться от нескольких лишних присваиваний. Будет вот так:

x2 := x_corS + _x; // Избавление ещё от лишних сложений типа x + _x
 for x := x_corS to _B_in.Width - 1 - x_cor do begin
   with RowIn[x] do begin
     InBlue  := rgbtBlue;
     InGreen := rgbtGreen;
     InRed  := rgbtRed;
   end;
   if not ((InRed = rc1) and (InGreen = gc1) and (InBlue = bc1)) then
   with RowOut[x2] do begin
     _r := rgbtRed + Trunc((InRed - rgbtRed) * D);
     if _r > 255 then rgbtRed := 255
       else if _r < 0 then rgbtRed := 0
       else rgbtRed := _r;

     _g := rgbtGreen + Trunc((InGreen - rgbtGreen) * D);
     if _g > 255 then rgbtGreen := 255
       else if _g < 0 then rgbtGreen := 0
       else rgbtGreen := _g;

     _b := rgbtBlue + Trunc((InBlue - rgbtBlue) * D);
     if _b > 255 then rgbtBlue := 255
       else if _b < 0 then rgbtBlue := 0
       else rgbtBlue := _b;
   end;
   Inc(x2);
 end;


 
Antonn ©   (2005-10-23 20:09) [19]

Ан нет, провел тест еще раз, при довольно больших изображениях (800*600) и 400 копированиях. Появилось отличие в производительности на ~11%, конечно нужно пересмотреть весь код, а то каждому пользователю необходимо копировать 400 раз картинку 800*600 :)

Я вот чем сильно интерсуюсь - быстрый поворот изображения, быстрее чем у меня. Может позаменять функции на ассемблер? Жаль только, я его не знаю:(


 
Fenik ©   (2005-10-23 22:10) [20]

Я тоже потестировал :)
Celeron 600

Out: 1024 x 768
In:  545 x 385
Число итераций - 35

Fenik - 3275,88 ms
Fenik - 3220,36 ms
Fenik - 3215,20 ms
----------
Среднее Fenik - 3237,15 ms

Antonn - 4766,58 ms
Antonn - 4764,01 ms
Antonn - 4745,72 ms
----------
Среднее Antonn - 4758,77 ms

Fenik быстрее Anton на 31,98 %


Могу код теста привести.
Так что, думаю с ассемблером заморачиваться не стоит, а вот над элементарной оптимизацией подумать.

> Antonn ©  (23.10.05 20:09) [19]
> Я вот чем сильно интерсуюсь - быстрый поворот изображения, быстрее чем у меня. Может позаменять функции на ассемблер? Жаль только, я его не знаю:(


Видел статью MBo на этом сайте?


 
Fenik ©   (2005-10-23 22:16) [21]

> Antonn ©  (23.10.05 20:09) [19]
> конечно нужно пересмотреть весь код, а то каждому пользователю необходимо копировать 400 раз картинку 800*600 :)


Не нужно 400 раз копировать, достаточно одного %-)

Out: 748 x 503
In:  640 x 480
Число итераций - 1

Fenik - 190,09 ms
Fenik - 150,46 ms
Fenik - 146,45 ms
----------
Среднее Fenik - 162,34 ms

Antonn - 200,27 ms
Antonn - 204,24 ms
Antonn - 200,64 ms
----------
Среднее Antonn - 201,72 ms

Fenik быстрее Anton на 19,52 %


 
Kerk ©   (2005-10-24 01:56) [22]

Ну почему бы все это не обсудить в комментариях к исходнику в Кладовке? Они ж для того и нужны? :)

Комментируют что-то мало :(


 
Antonn ©   (2005-10-24 06:29) [23]

Fenik ©   (23.10.05 22:10) [20]
Видел статью MBo на этом сайте?

нет, не видел. а какая?


 
Fenik ©   (2005-10-24 11:45) [24]

http://www.delphimaster.ru/articles/pixels/index.html


 
Antonn ©   (2005-10-24 12:52) [25]

Fenik ©   (24.10.05 11:45) [24]
как я понял, отличие от scanline лишь в универсальности.


 
WondeRu ©   (2005-10-25 12:02) [26]

Kerk ©   (20.10.05 1:07) [10]
В топку.


разумные доводы есть???


 
Kerk ©   (2005-10-25 19:15) [27]

WondeRu ©   (25.10.05 12:02) [26]
разумные доводы есть???


Нефиг использовать малораспространенные технологии.


 
Fenik ©   (2005-10-25 22:51) [28]

> Antonn ©  (24.10.05 12:52) [25]
> как я понял, отличие от scanline лишь в универсальности.


А сравнить по скорости религия не позволяет?

> WondeRu ©  (25.10.05 12:02) [26]
> разумные доводы есть???


GDI+ вирусы в картинках запускает! :о))


 
Fenik ©   (2005-10-30 00:33) [29]

> Antonn ©
> Я вот чем сильно интерсуюсь - быстрый поворот изображения, быстрее чем у меня. Может позаменять функции на ассемблер? Жаль только, я его не знаю:(


Воть:

procedure RotateOptimized(Src, Dest: TBitmap; Angle: Double; BackColor: TColor);
{
Angle - угол поворота, в градусах.
Для каждой точки результирующего растра (Dest) находится
соответствующая точка исходного (Src) по формуле:
XOld = XCenter + (XNew - XCenter)*Cos(A) - (YNew - YCenter)*Sin(A)
YOld = YCenter + (XNew - XCenter)*Sin(A) + (YNew - YCenter)*Cos(A)
Если найденая точка (XOld, YOld) не принадлежит исходному растру, то
точка (XNew, YNew) на результирующем растре закрашивается цветом BackColor.
-------
В данной процедуре XCenter и YCenter заданы по умолчанию как
середины ширины и высоты нового изображения соответственно.
-------
Для случаев 90, 180, 270 градусов лучше написать отдельные процедуры.
}
const DegToRad = Pi / 180;
type  TRGBTripleArray = array [0..32768] of TRGBTriple;
     PRGBTripleArray = ^TRGBTripleArray;
var DestRow: PRGBTriple;
   SrcRow:  PRGBTripleArray;
   BackRGB: TRGBTriple;
   X, Y, xOld, yOld, xNew, yNew: Integer;
   W, H, ICos, ISin: Integer;
   DCos, DSin, Left, Top: Extended;
begin
 W := Src.Width;
 H := Src.Height;
 BackRGB.rgbtRed   := Lo(BackColor);
 BackRGB.rgbtGreen := Lo(BackColor shr 8);
 BackRGB.rgbtBlue  := Lo((BackColor shr 8) shr 8);
{ Определяем размеры результирующего растра }
 SinCos(Abs(Angle) * DegToRad, DSin, DCos);
 Dest.Width  := Round(Abs(W * DCos) + Abs(H * DSin));
 Dest.Height := Round(Abs(W * DSin) + Abs(H * DCos));
 Src.PixelFormat  := pf24Bit;
 Dest.PixelFormat := pf24Bit;

 SinCos(-Angle * DegToRad, DSin, DCos);
 ISin := Round(DSin * 65536);
 ICos := Round(DCos * 65536);
{ Выносим из цикла то, что можно вынести }
 Left := (W - Dest.Width * DCos + Dest.Height * DSin) / 2;
 Top  := (H - Dest.Width * DSin - Dest.Height * DCos) / 2;

 for Y := 0 to Dest.Height - 1 do begin
   DestRow := Dest.ScanLine[Y];
   xNew := Round((Left - (Y * DSin)) * 65536);
   yNew := Round((Top  + (Y * DCos)) * 65536);
   for X := 0 to Dest.Width - 1 do begin
     xOld := xNew shr 16; { N shr 16  =  N div 65536 }
     yOld := yNew shr 16;
     if (xOld >= 0) and (xOld < W) and (yOld >= 0) and (yOld < H) then
     begin
       SrcRow   := Src.ScanLine[yOld];
       DestRow^ := SrcRow[xOld];
     end
     else
       DestRow^ := BackRGB;
     Inc(DestRow);
     Inc(xNew, ICos);
     Inc(yNew, ISin);
   end;
 end;
end;


Быстрее твоего  на 30-40%.
А если использовать TQuickPixels из статьи MBo, то даже моя функция работает в 2-4 раза быстрее, чем есть сейчас со ScanLine. Если же ещё сделать оптимизацию методов SetPixels24 и GetPixels24, то вообще космическая скорость будет :))


 
Antonn ©   (2005-10-30 06:05) [30]

Fenik ©   (30.10.05 0:33) [29]
Быстрее твоего  на 30-40%.

и даже больше, по крайней мере на 999 копированиях битмапов 256х256:)
одно но, моя процедурка не подгоняет битмап вывода под свой размер, битмап вращается не только относительно центра, и накладывает с "прозрачным цветом".


 
Fenik ©   (2005-10-30 10:55) [31]

> Antonn ©  (30.10.05 06:05) [30]
> одно но, моя процедурка не подгоняет битмап вывода под свой размер, битмап вращается не только относительно центра, и накладывает с "прозрачным цветом".


Это да. У меня была несколько иная задача.



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

Форум: "Игры";
Текущий архив: 2006.05.21;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.54 MB
Время: 0.012 c
15-1145868036
Looser
2006-04-24 12:40
2006.05.21
вопрос не по дельфи


4-1140892068
spokoistvie
2006-02-25 21:27
2006.05.21
TextViewer


6-1132520314
Alex23xandR
2005-11-20 23:58
2006.05.21
Кто качает?


2-1146693377
Std
2006-05-04 01:56
2006.05.21
Распаковка Zlib


2-1146207157
gerakla
2006-04-28 10:52
2006.05.21
Помогите мну





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