Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.05.21;
Скачать: CL | DM;

Вниз

[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;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.074 c
2-1146333488
sarafat
2006-04-29 21:58
2006.05.21
http


1-1144745826
MiHoY
2006-04-11 12:57
2006.05.21
поиск дочернего окна


2-1146411533
Yo-yo
2006-04-30 19:38
2006.05.21
TadvMemo


2-1146682017
Golik
2006-05-03 22:46
2006.05.21
Запуск Программы.


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