Форум: "Игры";
Текущий архив: 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 600Out: 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