Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.03.23;
Скачать: CL | DM;

Вниз

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 вся ветка

Текущий архив: 2008.03.23;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.024 c
15-1202741305
БарЛог
2008-02-11 17:48
2008.03.23
Статья о передаче файлов потоком


15-1202886931
Iam
2008-02-13 10:15
2008.03.23
SkypePro


2-1203397094
Ultimate
2008-02-19 07:58
2008.03.23
Компонент WebBrowser


15-1202689997
Petr V. Abramov
2008-02-11 03:33
2008.03.23
Хочешь узнать, что произошло в декабре 2007-го года в России? :))


2-1203529658
voe
2008-02-20 20:47
2008.03.23
работа с координатами.