Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизВывод картинки с прозрачным цветом - сдела криво, как правильнее? Найти похожие ветки
← →
TheEd (2012-09-19 12:03) [0]Господа Мастера!
В двух словах есть компонент, в задачи которого входит вывести на свою канву сначала фоновый TImage, потом как бы поверх него (в реальности на ту же канву), некоторый TPicture так, чтобы определённый цвет не выводился (был бы прозрачным).
Помучившись и не найдя другого решения, я сделал так:
ввел два дополрительных TBitmap в которых храню маски для дальнейшего комбинирования OR"ом и AND"ом. Получилось вот что:
FBackImage : TImage; // фоновый пикчур
FImageUp : TPicture; // пикчур что выводится поверх
FTransparentColorUp : TColor; // прозрачный цвет пикчура
FBackImageMaskUpAND : TBitmap; // маски
FBackImageMaskUpOR : TBitmap; // маски
...
// выводим фон
CopyMode := cmSrcCopy;
CopyRect(myRect, BackImage.Picture.Bitmap.Canvas, SomeRect);
// вычисляем маски - это жесть :)
if (FImageUp.Bitmap <> nil) and (not FImageUp.Bitmap.Empty) then
with FImageUp.Bitmap do
begin
FBackImageMaskUpAND.Width := Width;
FBackImageMaskUpAND.Height := Height;
FBackImageMaskUpOR.Width := Width;
FBackImageMaskUpOR.Height := Height;
for i := 0 to Width - 1 do
for j := 0 to Height - 1 do
if Canvas.Pixels[i, j] = FTransparentColorUp
then begin
FBackImageMaskUpOR.Canvas.Pixels[i,j] := $00000000;
FBackImageMaskUpAND.Canvas.Pixels[i,j] := $00FFFFFF;
end
else begin
FBackImageMaskUpOR.Canvas.Pixels[i,j] := $00FFFFFF;
FBackImageMaskUpAND.Canvas.Pixels[i,j] := Canvas.Pixels[i, j];
end;
end;
// выводим пикчур
CopyMode := cmSrcPaint;
CopyRect(SomeRect1, FBackImageMaskUpOR.Canvas, SomeRect2);
CopyMode := cmSrcAnd;
CopyRect(SomeRect1, FBackImageMaskUpAND.Canvas, SomeRect2);
Данный код тормозит при старте т.к. компонентов несколько десятков, и каждый вычисляет свои маски.
Совершенно очевидно что есть более "правильный способ". Помогите плиз!
← →
icWasya © (2012-09-19 13:40) [1]Для битмапов - см в сторону ScanLine
← →
Dimka Maslov © (2012-09-19 13:46) [2]У TBitmap есть свойства TransparentMode и TransparentColor
← →
TheEd (2012-09-19 15:38) [3]
> Для битмапов - см в сторону ScanLine
Как я понял ScanLine вернёт указатель на область памяти которую всё же перебирать побайтно надо. Насколько это будет быстрее чем доступ к пикселам канвы?
← →
TheEd (2012-09-19 15:41) [4]
> У TBitmap есть свойства TransparentMode и TransparentColor
да, но я как только его не пробовал прорисовывать, оно не работает в методе CopyRect... Если я не прав - ткните плиз носом.
← →
Плохиш © (2012-09-19 15:54) [5]http://www.google.de/#hl=de&sclient=psy-ab&q=delphi%20draw%20bitmap%20transparent&oq=&gs_l=&pbx=1&bav=on.2,or.r_gc.r_pw.r_qf.&fp=8e4aa2aca92b6bd5&bi w=1034&bih=592&pf=p&pdl=300
первая же ссылка с примером, буквально, из 3х строк.
← →
TheEd (2012-09-19 17:27) [6]
> Плохиш © (19.09.12 15:54) [5]
> первая же ссылка с примером, буквально, из 3х строк.
Спасибо, кажется то что надо, счас буду пробовать!
← →
TheEd (2012-09-19 18:26) [7]Так, косячок - вспомнил наконец то в чём:
я использовал не Canvas.Draw, а Canvas.CopyRect для того, чтобы мастшабировать пикчур при выводе! Draw работает без проблем, а вот CopyRect - льёт без учёта транспарента :(
← →
Dimka Maslov © (2012-09-19 18:53) [8]
> Насколько это будет быстрее чем доступ к пикселам канвы
Более 9000 раз. Я гарантирую это.
Доступ к пикселам канвы осуществляется через функции GDI с множеством лишних операций, которые перезаинкапсулировано обращаются таки к области памяти.
← →
TheEd (2012-09-19 19:16) [9]
> Более 9000 раз. Я гарантирую это.
спасибо, поэкспериментирую.
Кстати нашёл метод как обойти маштабирование с транспарентом: завожу второй битмап нужного размера, на него CopyRect"ом втискиваю пикчур, а потом его рисую Draw"ом на нужную канву. Примерно так:procedure TForm1.Button6Click(Sender: TObject);
var
b1, b2 : TBitMap;
begin
b1 := TBitmap.Create;
b2 := TBitmap.Create;
try
with b2 do
LoadFromFile("C:\SomePicture.bmp");
with b1 do
begin
PixelFormat := pf32bit;
HandleType := bmDIB;
Width := b2.Width * 2;
Height := b2.Height div 2;
Transparent := TRUE;
TransparentColor := clWhite;
end;
with b1.Canvas do
CopyRect(Rect(0,0,b1.Width,b1.Height), b2.Canvas, Rect(0,0,b2.Width,b2.Height));
Canvas.Draw(50,50,b1);
finally
b1.Free;
b2.Free;
end;
end;
← →
брат Птибурдукова (2012-09-19 20:50) [10]
> TheEd (19.09.12 18:26) [7]
Автоматическое масштабирование прозрачности — в любом случае тема больная...
← →
TheEd (2012-09-20 12:56) [11]
> Автоматическое масштабирование прозрачности — в любом случае
> тема больная...
да, согласен - огород я в своё время нагородил (см. пост 1) аж ужас. Но решение найдено (пост 9) теперь вроде гемор снят с повестки дня...
Всем поучавствовашим - большое спасибо!
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.087 c