Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Как загрузить картинку в компонент


Автор: Emulator 30.4.2004, 18:36
Как загрузить картинку в компонент
ImageList так чтобы она имела свойство прозрачности.


var BMP:TBitmap;

BMP:= TBitmap.Create;
BMP.LoadFromFile(MFile);
Immages.Add(BMP,BMP);
BMP.Free;

Автор: _hunter 30.4.2004, 18:54
DrawingStyle = dsTransparent?

Автор: Emulator 30.4.2004, 22:50
Нет нужно чтоб розовый фон вокруг картинки был невидим

Автор: Medved 1.5.2004, 11:14
Нижний левый пиксель, всегда является цветом прозрачности.

Автор: Emulator 1.5.2004, 17:05
И что дальше делать ?

Автор: Medved 2.5.2004, 02:02
А ничего.
Повторюсь, если вы хотите сделать какие-либо области прозрачными, закрасте их таким цветом, какой в нижнем левом пикселе картинки. Ну а затем загрузите этот битмап в TImageList и радуйтесь результату.

Автор: z-END 2.5.2004, 02:25
А че серьезно нижний левый?
А я то постоянно к верхнему левому привязывал ну [1,1] типа. withstupid.gif

Автор: p0s0l 2.5.2004, 16:55
nJIaKca.spb, да серьёзно. Видимо у тебя эти два пиксела всегда совпадали...

Автор: Emulator 3.5.2004, 06:54
А как определить Цвет Картинки ?

Автор: x77 3.5.2004, 16:20
Pegas, p0s0l, с чего это левый нижний? битмапы бывают двух разных видов, top-down и bottom-up, что соответствует порядку загрузки "строк" пикселей. по умолчанию (т.е. TransparentMode = tmAuto) прозрачность определяет первый пиксел в массиве данных, который может быть как левым нижним, так и левым верхним, в зависимости от типа битмапа. помимо режима по умолчанию, есть режим принудительный, tmFixed, если мне не изменяет память, который включается автоматом при установке свойства TransparentColor.

это означает, что если надо сделать розовый цвет прозрачным, надо просто сказать Bmp.TransparentColor := clFuchsia

Добавлено @ 16:23
Emulator, а что считается "цветом картинки"? smile.gif

Автор: p0s0l 3.5.2004, 18:28
x77, конечно, всё это очень поучительно... Но либо я такой отставший от жизни, либо ты заблуждаешься. Почему-то ниразу мне не приходилось за прозрачность брать левый верхний символ - или вымерли bmp такого вида ?
Кстати, бывает иногда полезно заглянуть в хелп:
Цитата
When TransparentMode is set to tmAuto (the default), the TransparentColor property returns the color of the bottom-leftmost pixel of the bitmap image.

Нигде нет оговорки про зависимость от формата bmp-шки.

Ладно, что там гадать - взял файл "a.bmp" - скопировал его в файл "b.bmp", в Hex-Edit'е поменял свойство Height на отрицательное (было 80h, стало FFFFFF80h), проверил в ACDSEE - теперь одна картинка стала перевернутой копией другой. Загружал эти две картинки в TImage, TImageList - в обоих случаях берется левый нижний пиксел битмапа, независимо от того, перевернутый битмап или нет. Так что твои суждения оказались неверными насчет первого байта данных...


Автор: Emulator 3.5.2004, 18:30
Народ Так как Определить Цвет (Левый верхний) ? Если можно то кодом.

Автор: p0s0l 3.5.2004, 19:08
У ImageList свойство Masked должно быть True.
Свойство DrawingStyle оставь по-умолчанию - dsNormal.

Вместо ImageList.Add(Bmp, Bmp) делай так:
ImageList1.AddMasked(Bmp, Bmp.Canvas.Pixels[0, 0]); - тогда верхний левый пиксел будет определять цвет прозрачности
или же можешь принудительно задать цвет прозрачности:
ImageList1.AddMasked(Bmp, clFuchsia);

Автор: Emulator 3.5.2004, 22:07
Спасибо Посол!

Автор: x77 4.5.2004, 10:32
p0s0l, правильно, давай друг друга справками давить:

Цитата

Determines which color of the bitmap is to be transparent when the bitmap is drawn.

property TransparentColor: TColor;

Description

Use TransparentColor to determine how to draw the bitmap transparently. When the TransparentMode property is set to tmAuto (default), TransparentColor returns the color of the first pixel in the bitmap image data. For "bottom-up" bitmaps, the first pixel is the bottom leftmost pixel shown onscreen. For "top-down" bitmaps (less common), the first pixel is in the top left corner shown onscreen.

If TransparentColor is assigned, the TransparentMode is automatically set to tmFixed so that the new transparent color can be used later. If you want TransparentColor to disregard any assignments and return the bottom leftmost pixel color again, set TransparentMode to tmAuto.


ты "свою" справку дочитай до конца: TransparentMode определяет, является ли цвет прозрачности высчитываемым автоматически, или берётся из фиксированного значения в битмапе. если он равен tmFixed, то он берётся либо из левого нижнего, либог из левого верхнего в зависимости от типа битмапа. установка свойства TransparentColor автоматом ставит TransparentMode в tmFixed, запрещая, таким образом, автоматическое определение цвета прозрачности.

со справкой разобрались. теперь разберёмсяс кодом:

Код

function TCustomImageList.AddMasked(Image: TBitmap; MaskColor: TColor): Integer;
var
 ImageDDB: TBitmap;
begin
 ImageDDB := TBitmap.Create;
 try
   if Masked and (MaskColor <> -1) then
   begin
     with TBitmap.Create do
     try
       Assign(Image);

       { обрати внимание на следующую строчку }
       TransparentColor := MaskColor;

       Self.HandleNeeded;
       Result := ImageList_Add(Self.FHandle, GetImageHandle(Image, ImageDDB),
         GetBitmapHandle(MaskHandle));
     finally
       Free;
     end;
   end
   else Result := ImageList_Add(Handle, GetImageHandle(Image, ImageDDB), 0);
 finally
   ImageDDB.Free;
 end;
 Change;
end;


что разницы нет, сказать Bmp.TransparentColor := clFuchsia, как изначально предлагал я, или ImageList.AddMasked (Bmp, clFuchsia), как предлагаешь ты. и в чём моё заблуждение - я пока так и не понял.

смысла твоих манипуляций с HexEdit'ом я, если честно, тоже не понял. sad.gif

Автор: p0s0l 6.5.2004, 14:31
Ну вот, x77 на меня взъелся (совершенно притом несправедливоsad.gif)...
Я сказал, что прозрачный пиксел определяется левым нижним пикселом картинки. На что ты ответил:
[quoute]Pegas, p0s0l, с чего это левый нижний? битмапы бывают двух разных видов, top-down и bottom-up, что соответствует порядку загрузки "строк" пикселей. по умолчанию (т.е. TransparentMode = tmAuto) прозрачность определяет первый пиксел в массиве данных, который может быть как левым нижним, так и левым верхним, в зависимости от типа битмапа.[/quote]
Отсюда ясно следует твоя мысль - что пиксел прозрачности может быть и ЛЕВЫМ ВЕРХНИМ.

Со справкой: Справки могут морально устаревать (их писали тоже люди, которые могли забыть изменить какой-нибудь абзац)... Ладно, проверим:
две одинаковых (по содержанию) картинки: одна top-down, другая bottom-up:
Код
var
 bmp : TBitmap;
begin
 bmp := TBitmap.Create;
 bmp.LoadFromFile('c:\a.bmp');
 bmp.TransparentMode := tmAuto;
 Label1.Caption := IntToHex(bmp.TransparentColor, 8);
 Image1.Canvas.Draw(0, 0, bmp);

 bmp.LoadFromFile('c:\b.bmp');
 bmp.TransparentMode := tmAuto;
 Label2.Caption := IntToHex(bmp.TransparentColor, 8);
 Image2.Canvas.Draw(0, 0, bmp);
 bmp.Free;
end;

И что я вижу - Label1 и Label2 содержат разные значения, хотя сами данные картинок у них совпадают - т.е. берется в любом случае левый нижний пиксел, а не "the color of the first pixel in the bitmap image data"...
Видимо, в справке остался атавизм - может это было раньше так, но сейчас (в D7) точно не так (ниже приведу уже 100% доказательство), ведь правильнее за цвет прозрачности брать один и тот же пиксел картинки (не важно, верхний левый или нижний левый, лишь бы один и тот же). А то если я буду грузить картинку, я ж не знаю, какая она - topdown или bottomup ? Интересно будет, если я юзаю в проге кучу иконок, выдернутых из разных источников, половина одной ориентации, половина - другой...
Ладно, для пущей уверенности взглянем на один интересный метод TBitmap - установка свойства TransparentMode сводится в конце концов к вызову этого метода:
Код
function TBitmap.GetTransparentColor: TColor;
begin
 if FTransparentColor = clDefault then
 begin
   if Monochrome then
     Result := clWhite
   else
     Result := Canvas.Pixels[0, Height - 1]; //// <<<--- Только совсем неверующий не уверует после этого...
 end
 else Result := ColorToRGB(FTransparentColor);
 Result := Result or $02000000;
end;

И отсюда ясно видно, без всяких яких, какой же именно пиксел берется за цвет прозрачности...

Цитата
что разницы нет, сказать Bmp.TransparentColor := clFuchsia, как изначально предлагал я, или ImageList.AddMasked (Bmp, clFuchsia), как предлагаешь ты.

Лучше бы проверил теорию на практике. Я всегда проверяю... Разница - есть!
Создай новый проект, засунь туда ImageList (и к примеру, ToolBar, а в нем две кнопки с ImageIndex=0 и ImageIndex=1), и попробуй код:
Код
var
 bmp : TBitmap;
begin
 bmp := TBitmap.Create;
 bmp.LoadFromFile('c:\a.bmp');
 bmp.TransparentColor := clYellow;
 ImageList1.Add(bmp, nil);

 bmp.LoadFromFile('c:\b.bmp');
 ImageList1.Add(bmp, nil);
 bmp.Free;
end;

Это было первое, что я попробовал. И tmAuto тоже не помогает - всё равно картинки без прозрачности. А вот это уже работает:
Код
var
 bmp : TBitmap;
begin
 bmp := TBitmap.Create;
 bmp.LoadFromFile('c:\a.bmp');
 ImageList1.AddMasked(bmp, clYellow);

 bmp.LoadFromFile('c:\b.bmp');
 ImageList1.AddMasked(bmp, clYellow);
 bmp.Free;
end;

Так что разница есть...

Цитата
и в чём моё заблуждение - я пока так и не понял
Ответ:
Цитата
Так что твои суждения оказались неверными насчет первого байта данных...


Цитата
смысла твоих манипуляций с HexEdit'ом я, если честно, тоже не понял.

А ты как думал определяется ориентация картинки ? По желанию программиста что-ли ? Top-down и bottom-up ориентация определяется значением поля biHeight у структуры BITMAPINFOHEADER:
Цитата

biHeight
Specifies the height of the bitmap, in pixels. If biHeight is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If biHeight is negative, the bitmap is a top-down DIB and its origin is the upper-left corner.

Надеюсь, не надо объяснять, откуда взялось FFFFFF80 вместо 00000080 ?

Вывод: либо ты не проверяешь ниодного из своих доводов, либо сидишь на другой дельфи (помнишь аналогичную историю с DBGrid'ом ? Мы тоже там друг друга долго не могли понять... пока не выяснилось, что дело в разных версиях Delphi)...

Автор: x77 6.5.2004, 14:35
p0s0l, сейчас не могу предметно ответить, подыхаю. то ли отравился, то ли хрен его знает. позже отпишу.

но я ни в коем случае не взъелся smile.gif если был резок - извини.

Автор: p0s0l 6.5.2004, 14:46
x77, главное - не подыхай! Куда мы тут без тебя ?
А спор - это фигня... В итоге оба окажемся неправы, или оба правы smile.gif

Автор: Guest 6.5.2004, 16:04
Цитата
x77, главное - не подыхай! Куда мы тут без тебя ?
А спор - это фигня... В итоге оба окажемся неправы, или оба правы 


Ты прав в итоге вы оба не правы.

*.bmp не
Цитата

бывают двух разных видов, top-down и bottom-up, что соответствует порядку загрузки "строк"


Это взято из описания формата *.bmp
Цитата

..............ЗДЕСЬ ОПИСАНИЕ СТРУКТУРЫ ФАЙЛА........... если кому интересно могу выложить
После того, как все параметры битового образа определены, в файле идут сами скан-строки битовой плоскости, причем первой скан-строкой в формате DIB считается нижняя скан-строка (т.е. начало координат находится в левом нижнем углу изображения).

Автор: p0s0l 6.5.2004, 16:28
Даммм.... Щас тут будут цитировать строки неизвестных авторов из неизвестных описаний... Если я найду описание bmp, где написано, что пикселы в нем располагаются по синусоидам, и процитирую это - нормально будет ? Это 100%, что bmp могут быть верхтормашками расположены, и наоборот... Против этого не попрешь - и Photoshop умеет сохрянать разными ориентациями, и в MSDN написано об ориентациях, и MS API Reference тоже... Так что, гость, тут ты сам ошибаешься...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)