Форум: "Media";
Текущий архив: 2008.03.23;
Скачать: [xml.tar.bz2];
ВнизPNG с альфа каналом в DDS. Найти похожие ветки
← →
Sholah_Weras © (2007-04-24 20:09) [0]Здравствуйте.
Боюсь, сам никак не дотренькаю. Суть проблемы.
Юзаю библиотеку Vampyre Imaging Library, которая кроме всего прочего, позволяет сохранять файлы в формат DDS. Вообще, по идее, надо на выходе получить файл с несколькоми изображениями, размещенными последовательно. Это я (спасибо мастерам), с горем пополам сделал.
var
FBit: TImagingBitmap; // Все из библиотеки
FImage: TMultiImage; // Vampyre
PNG: array of TImagingPNG; //
FBit:= TImagingBitmap.Create;
FBit.Width := PNG[0].Width * Length(PNG);
FBit.Height := PNG[0].Height;
For i := 0 To Length(PNG) - 1 Do
Begin
FBit.Canvas.Draw(X, 0, PNG[i]);
Inc(X, PNG[0].Width);
End;
FImage := TMultiImage.Create;
FImage.Assign(FBit);
Но проблема в том, что альфа-канал не сохраняется. Если просто взять картинку .png и переконвертировать - то все нормально, альфа есть. А вот если копировать таким образом - то не сохраняется.
Поможите, люди добрые :)
← →
Krupsky (2007-04-24 21:32) [1]>FBit.Canvas.Draw(X, 0, PNG[i]);
Ага, так не будет. Альфу надо отдельно копировать, работая, по всей видимости (тонкостей твоей библиотеки не просёк) с 32-битными битмапами.
← →
Sholah_Weras © (2007-04-24 21:50) [2]А как альфу то выделять из файла, т.е. - можно поподробнее про 32-битные битпамы и их использование в данной задаче?
← →
Krupsky (2007-04-24 22:17) [3]Ну смотри. У тебя есть некий фон, любой битмап, и ты на него рисуешь PNG с альфа-каналом, т.е. какие то части полностью прозрачны, какие-то полупрозрачны, какие-то совсем непрозрачны. По сути это 32-битный битмап - 3 канала цветов и 1 канал - альфа-канал, маска и оттенков серого. Когда ты его рисуешь, компьютер для каждого пикселя берёт цвет фона, цвет битмапа, желаемую прозрачность и на этой основе расчитывает новый цвет, который и рисует. При этом альфа-канал на новом изображении конечно же не меняется. Вот это то, что ты делаешь путём FBit.Canvas.Draw(X, 0, PNG[i]); Не понимаю, почему таким образом должен копироваться и альфа-канал.
Про 32-битные изображения почитать можно здесь:
http://www.efg2.com/Lab/ImageProcessing/Scanline.htm
← →
Sholah_Weras © (2007-04-25 09:09) [4]Я вот тут немного не понял:
"При этом альфа-канал на новом изображении конечно же не меняется"
и
"Не понимаю, почему таким образом должен копироваться и альфа-канал"
То ли противоречие, то ли я не понял :)
За ссылку отдельное спасибо, но я так и не понял, как же мне тогда сделать один файл с картинками и с альфа каналом?
← →
antonn (work) (2007-04-25 10:37) [5]если файлы нужно хранить только для себя, то можно сделать свой формат. Просто сохранить битмапы в стрим и все. Вот есть примерный класс - http://antonn.ru/index.php?view=zip&file=7ffdc510_1177482635.zip (2кб)
только там используются 32 битные битмапы, но легко добавляются и проверка на другие. ТАк же можно прикрутить упаковку zlib, тогда весить меньше будут.
← →
Sholah_Weras © (2007-04-25 14:37) [6]2 antonn
А можно ссылку на пример с альфой, а то мне так трудно понять что к чему.
← →
Krupsky (2007-04-25 18:24) [7]Скачал я Vampyre Imaging Library, посмотрел класс TImagingPNG - а там свойство Scanline. А это уже полдела. Вот пример вывода png-картинки на форму вручную с доступом к альфа-каналу:
const
PixelCountMax = 32768;
type
pRGBQuad = ^TRGBQuad;
TRGBQuad = packed record
rgbBlue : Byte;
rgbGreen : Byte;
rgbRed : Byte;
rgbReserved : Byte;
end;
type
pRGBQuadArray = ^TRGBQuadArray;
TRGBQuadArray = array[0..PixelCountMax-1] of TRGBQuad;
function BlendColors(const Color1, Color2: TColor; Amount: Extended): TColor;
var
R, R2, G, G2, B, B2: Integer;
win1, win2: Integer;
begin
win1 := ColorToRGB(Color1);
win2 := ColorToRGB(Color2);
R := GetRValue(win1); R2 := GetRValue(win2);
G := GetGValue(win1); G2 := GetGValue(win2);
B := GetBValue(win1); B2 := GetBValue(win2);
B2 := Round((1 - Amount) * B + Amount * B2);
G2 := Round((1 - Amount) * G + Amount * G2);
R2 := Round((1 - Amount) * R + Amount * R2);
if R2 < 0 then R2 := 0; if R2 > 255 then R2 := 255;
if G2 < 0 then G2 := 0; if G2 > 255 then G2 := 255;
if B2 < 0 then B2 := 0; if B2 > 255 then B2 := 255;
Result := TColor(RGB(R2, G2, B2));
end;
procedure DrawTo(Pic: TImagingPNG; Dst: TCanvas; x, y: Integer);
var
x0, y0: Integer;
TempColor: TColor;
RowS: pRGBQuadArray;
begin
for y0 := y to y + Pic.Height-1 do
begin
RowS := Pic.Scanline[y0-y];
for x0 := x to x + Pic.Width-1 do
begin
TempColor := BlendColors(
TColor(ColorToRGB(Dst.Pixels[x0,y0])),
TColor(RGB(RowS[x0-x].rgbRed, RowS[x0-x].rgbGreen, RowS[x0-x].rgbBlue)),
RowS[x0-x].rgbReserved / 256);
Dst.Pixels[x0,y0] := tempColor;
end;
end;
end;
procedure TformMain.btnProcessClick(Sender: TObject);
var
png: TImagingPNG;
begin
png := TImagingPNG.Create;
try
png.LoadFromFile("test.png");
if png.PixelFormat = pf32bit then
DrawTo(png, Canvas, 50, 50);
finally
png.Free;
end;
end;
← →
Sholah_Weras © (2007-04-25 18:45) [8]
Splice.PixelFormat := pf32bit;
Splice.Width := PNG[0].Width * Length(PNG);
Splice.Height := PNG[0].Height;
For i := 0 To Length(PNG) - 1 Do
Begin
Splice.Canvas.Draw(X, 0, PNG[i]);
Inc(X, PNG[0].Width);
End;
Splice: TImagingBitmap;
Все дело в pf32bit.
Все спасибо))
← →
Sholah_Weras © (2007-04-25 18:47) [9]2 Krupsky
Извини, что заставил выкачивать, пять минут назад только сделал) Спасибо за помощь)
Страницы: 1 вся ветка
Форум: "Media";
Текущий архив: 2008.03.23;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.006 c