Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
11-1186278717
ElectriC
2007-08-05 05:51
2008.03.23
Проблем-ка с TIcon


15-1202771270
Petr V. Abramov
2008-02-12 02:07
2008.03.23
Вернут ли Подгорецкому газ?


2-1202308435
dusha
2008-02-06 17:33
2008.03.23
Динамическая вставка фрейма в форму?


15-1202872059
Slider007
2008-02-13 06:07
2008.03.23
С днем рождения ! 13 февраля 2008 среда


2-1203632100
максим
2008-02-22 01:15
2008.03.23
хук в dll





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