Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1346143882
FIL-23
2012-08-28 12:51
2013.03.22
ehlib


2-1332423903
Cobalt
2012-03-22 17:45
2013.03.22
AnsiString[128] - "; Expected ; but received [ at line"


15-1329646997
Чайник
2012-02-19 14:23
2013.03.22
Direct 3D и Delphi 2010


15-1345910897
Чтец
2012-08-25 20:08
2013.03.22
Ищу книгу


2-1335041434
SiDimka
2012-04-22 00:50
2013.03.22
Как передать фокус окну





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