Главная страница
    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.011 c
2-1203702578
Igor23
2008-02-22 20:49
2008.03.23
Глупый вопрос...новсе же Memo


15-1202563191
Michael5
2008-02-09 16:19
2008.03.23
Переименовал учетную запись на компе, а имя пользовательской папк


15-1202729706
{RASkov}
2008-02-11 14:35
2008.03.23
Запомнить параметры для каждой папки


15-1202674320
Small Donkey
2008-02-10 23:12
2008.03.23
В помощь програмисту


2-1203580401
aleyna
2008-02-21 10:53
2008.03.23
паралельно





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