Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2007.03.25;
Скачать: [xml.tar.bz2];

Вниз

32-битные изображения в Delphi   Найти похожие ветки 

 
EV   (2006-07-10 16:03) [0]

Подскажите пожалуйста как в Delphi прорисовыватьь 32-битные изображения (или иконки) с Alpha каналом? Что для этого нужно?


 
antonn ©   (2006-07-10 16:30) [1]

32-битные изображения бывают разные. Пример для TBitmap с pf32bit:
(_B_in - 32-битный битмап, _B_out - 24-битный битмап, на него выводится, _x,_y - координаты вывода)
procedure CopyBitmapAlfa32to24(_B_in,_B_out:Tbitmap; _x,_y:integer);
const
 MaxPixelCountA = MaxInt div SizeOf(TRGBQuad);
 MaxPixelCount = MaxInt div SizeOf(TRGBTriple);
type
 PRGBArray = ^TRGBArray;
 TRGBArray = array[0..MaxPixelCount-1] of TRGBTriple;
 PRGBAArray = ^TRGBAArray;
 TRGBAArray = array[0..MaxPixelCountA-1] of TRGBQuad;
var x, y: Integer; _r,_b,_g:integer;
   w_in,h_in,w_out,h_out,tmp,x_cor,y_cor,x_corS,y_corS: Integer;
   RowOut:PRGBArray; RowIn:PRGBAArray;
   _d,_dd:double;
begin
w_in:=_B_in.Width;
h_in:=_B_in.Height;
w_out:=_B_out.Width;
h_out:=_B_out.Height;
if (_x)>w_out-1 then exit; if (_x+w_out)<0 then exit;
if (_y)>h_out-1 then exit; if (_y+h_out)<0 then exit;

if _x<0 then x_corS:=abs(_x) else x_corS:=0;
if _y<0 then y_corS:=abs(_y) else y_corS:=0;
if (_x+w_in)>w_out then x_cor:=_x+w_in-w_out else x_cor:=0;
if (_y+h_in)>h_out then y_cor:=_y+h_in-h_out else y_cor:=0;

 y_cor:=h_in-1-y_cor;
 tmp:=w_in-1-x_cor; _dd:=(100/255)/100;
 for y:=y_corS to y_cor do begin
    RowOut:= _B_out.ScanLine[y+_y];
    RowIn:= _B_in.ScanLine[y];
   for x:=x_corS to tmp do begin
        _d:=RowIn[x].rgbReserved*_dd;

         _r:= trunc(RowOut[x+_x].rgbtRed+(RowIn[x].rgbRed-RowOut[x+_x].rgbtRed)*_d);
        if _r>255 then _r:=255 else if _r<0 then _r:=0;

        _g:= trunc(RowOut[x+_x].rgbtGreen+(RowIn[x].rgbGreen-RowOut[x+_x].rgbtGreen)*_d);
        if _g>255 then _g:=255 else if _g<0 then _g:=0;

        _b:= trunc(RowOut[x+_x].rgbtBlue+(RowIn[x].rgbBlue-RowOut[x+_x].rgbtBlue)*_d);
        if _b>255 then _b:=255 else if _b<0 then _b:=0;

         RowOut[x+_x].rgbtRed:=_r;
         RowOut[x+_x].rgbtGreen:=_g;
         RowOut[x+_x].rgbtBlue:=_b;

 end; end;
end;

код старый, местами "неумный", есть простор для оптимизаций и пр.


 
miek ©   (2006-07-11 08:08) [2]

Код совершенно непонятный.
Для каждого пиксела: (A-прозрачность накладываемого спрайта, X-значение цвета одного канала в исходном спрайте, Y - в накладываемом, Z - результат)
Z = (1-A)*X + A*Y
И так для всех 3-х каналов и для всех пикселов. Можно извлекать прозрачность из альфа-канала, а можно подставлять постоянную.
Естественно, оба спрайта желательно иметь 32-битные.


 
antonn ©   (2006-07-11 08:57) [3]

miek ©   (11.07.06 8:08) [2]
Естественно, оба спрайта желательно иметь 32-битные.

а если это не естественно для автора?
код, приведенный мной копирует 32 битный битмап на 24 битный (который без альфаканала).
по формуле - если копировать 32 на 32, то нужно учитывать бит альфаканала "приемника", чтобы не заменить его более светлым из иконки.
по моей формуле: Z = X+(Y-X)*(A/255)


 
EV   (2006-07-11 16:55) [4]

ОГРОМНОЕ СПАСИБО


 
EV   (2006-07-12 12:07) [5]

Вот мой доработанный код. 32-битное (либо другое) изображение накладывается на фоновое изображение.


procedure CopyBitmapAlfa32to24(SrcBitmap: TBitmap; var DestBitmap: TBitmap;
x,y: Integer; AlphaBlendValue: Byte);
const
MaxPixelCountA = MaxInt div SizeOf(TRGBQuad);
MaxPixelCount = MaxInt div SizeOf(TRGBTriple);
type
{PRGBArray = ^TRGBArray;
TRGBArray = array[0..MaxPixelCount-1] of TRGBTriple; }
PRGBAArray = ^TRGBAArray;
TRGBAArray = array[0..MaxPixelCountA-1] of TRGBQuad;
var
i, j: integer;
r1, g1, b1, r, g, b, r2, g2, b2, alpha: byte;
a: Real;
RowIn: PRGBAArray;
c, c1: Cardinal;
//RowOut: PRGBArray;
begin
x:=Abs(x);
y:=Abs(y);

if x+SrcBitmap.Width > DestBitmap.Width then Exit;
if y+SrcBitmap.Height > DestBitmap.Height then Exit;

for j:=0 to SrcBitmap.Height-1 do
 begin
 RowIn:=SrcBitmap.ScanLine[j];
 for i:=0 to SrcBitmap.Width-1 do
 begin
  if SrcBitmap.PixelFormat = pf32bit then
  begin
   Alpha:=RowIn[i].rgbReserved;
   r1:=RowIn[i].rgbRed;
   g1:=RowIn[i].rgbGreen;
   b1:=RowIn[i].rgbBlue;
  end
   else
  begin
   Alpha:=AlphaBlendValue;
   c1:=SrcBitmap.Canvas.Pixels[i,j];
   r1:=GetRValue(c1);
   g1:=GetGValue(c1);
   b1:=GetBValue(c1);
  end;

  a:=alpha/255;

  c:=DestBitmap.Canvas.Pixels[x+i,y+j];
  r:=GetRValue(c);
  g:=GetGValue(c);
  b:=GetBValue(c);

  r2:=Round((1-a)*r + a*r1);
  g2:=Round((1-a)*g + a*g1);
  b2:=Round((1-a)*b + a*b1);

  DestBitmap.Canvas.Pixels[x+i,y+j]:=RGB(r2,g2,b2);
 end;
 end;

end;


 
Степан   (2006-07-25 23:50) [6]

Могу в помощь выложить.... может пригодиться... самопальный набор, сделано для друга... выводит битмап по маске, но можно и проапгрейдить!


function GetGradientColor(Color1, Color2: TColor; BlockCount,
 BlockIndex: Integer): TColor;
var
 DifR, DifB, DifG: Integer;
 SR, SG, SB: Integer;
begin
 SR := Color1 and $FF;
 DifR := (Color2 and $FF) - SR;
 SG := (Color1 shr 8) and $FF;
 DifG := ((Color2 shr 8) and $FF) - SG;
 SB := (Color1 shr 16) and $FF;
 difb:=((Color2 shr 16) and $FF) - SB;
 Result := RGB((BlockIndex * DifR) div (BlockCount - 1) + SR,
   (BlockIndex * DifG) div (BlockCount - 1) + SG,
   (BlockIndex * DifB) div (BlockCount - 1) + SB);
end;

function DrawAlphaBitmap(const Canvas: TCanvas; var ColorBitmap,
 MaskBitmap: TBitmap; X, Y: Integer): Boolean;

type
 TArray = array [0..0] of Integer;

 function GetBitsColor(var Bits: Pointer; Width, Height: Integer;
 X, Y: Cardinal): Integer;
 begin
   Result := 0;
   try
     Result := TArray(Bits^)[X + Y * Width];
   except
   end;
 end;
 procedure SetBitsColor(var Bits: Pointer; Width, Height: Integer;
   X, Y: Cardinal; Color: Integer);
 begin
   try
     TArray(Bits^)[X + Y * Width] := Color;
   except
   end;
 end;

var
 ColorBits: Pointer;  // Массив пикселей исходного изображения
 MaskBits: Pointer;  // Массив пикселей маски изображения
 DestBitmap: HBITMAP;   // Дескриптор полученного изображения
 DestDC: HDC;  // Контекстное устройтво полученного изображения
 DestBits: Pointer;  // Массив пикселей полученного изображения
 BitmapInfo: TBitmapInfo;  // Информация об изображении
 Color1, Color2, MaskColor: Integer;  // Цвета
 CX, CY: Integer;  // Счтечики
begin
 Result := False;
 if (MaskBitmap.Width < ColorBitmap.Width) or (MaskBitmap.Width <
 ColorBitmap.Width) then
   Exit;
 // Получение массива пикселей для ColorBitmap
 GetMem(ColorBits, ColorBitmap.Width * ColorBitmap.Height *
   GetDeviceCaps(ColorBitmap.Canvas.Handle, BITSPIXEL));
 BitmapInfo.bmiHeader.biSize := SizeOf(TBitmapInfoHeader);
 BitmapInfo.bmiHeader.biWidth := ColorBitmap.Width;
 BitmapInfo.bmiHeader.biHeight := - ColorBitmap.Height;
 BitmapInfo.bmiHeader.biPlanes := 1;
 BitmapInfo.bmiHeader.biBitCount := GetDeviceCaps(ColorBitmap.Canvas.Handle,
   BITSPIXEL);
 BitmapInfo.bmiHeader.biCompression := BI_RGB;
 if GetDIBits(ColorBitmap.Canvas.Handle, ColorBitmap.Handle, 0,
 ColorBitmap.Height, ColorBits, BitmapInfo, DIB_RGB_COLORS) = 0 then
   Exit;
 // Получение массива пикселей для MaskBitmap
 GetMem(MaskBits, MaskBitmap.Width * MaskBitmap.Height *
   GetDeviceCaps(MaskBitmap.Canvas.Handle, BITSPIXEL));
 BitmapInfo.bmiHeader.biSize := SizeOf(TBitmapInfoHeader);
 BitmapInfo.bmiHeader.biWidth := MaskBitmap.Width;
 BitmapInfo.bmiHeader.biHeight := - MaskBitmap.Height;
 BitmapInfo.bmiHeader.biPlanes := 1;
 BitmapInfo.bmiHeader.biBitCount := GetDeviceCaps(MaskBitmap.Canvas.Handle,
   BITSPIXEL);
 BitmapInfo.bmiHeader.biCompression := BI_RGB;
 if GetDIBits(MaskBitmap.Canvas.Handle, MaskBitmap.Handle, 0,
   MaskBitmap.Height, MaskBits, BitmapInfo, DIB_RGB_COLORS) = 0 then
   Exit;
 // Создание DestBitmap и копирование в него содержимого контекстного
 // устройства DC
 BitmapInfo.bmiHeader.biSize := SizeOf(TBitmapInfoHeader);
 BitmapInfo.bmiHeader.biWidth := ColorBitmap.Width;
 BitmapInfo.bmiHeader.biHeight := - ColorBitmap.Height;
 BitmapInfo.bmiHeader.biPlanes := 1;
 BitmapInfo.bmiHeader.biBitCount := 32;
 BitmapInfo.bmiHeader.biCompression := BI_RGB;
 DestBitmap := CreateDIBSection(DIB_PAL_COLORS, BitmapInfo, DIB_RGB_COLORS,
   DestBits, 0, 0);
 DestDC := CreateCompatibleDC(Canvas.Handle);
 SelectObject(DestDC, DestBitmap);
 BitBlt(DestDC, 0, 0, ColorBitmap.Width, ColorBitmap.Height, Canvas.Handle, X,
   Y, SRCCOPY);

 // КОПИРОВАНИЕ!!!
 for CY := 0 to ColorBitmap.Height - 1 do
   for CX := 0 to ColorBitmap.Width - 1 do begin
     Color1 := GetBitsColor(DestBits, ColorBitmap.Width, ColorBitmap.Height,
       CX, CY);
     Color2 := GetBitsColor(ColorBits, ColorBitmap.Width, ColorBitmap.Height,
       CX, CY);
     MaskColor := GetBitsColor(MaskBits, MaskBitmap.Width, MaskBitmap.Height,
       CX, CY);
     Color1 := GetGradientColor(Color1, Color2, 256, GetMaxIntensity(MaskColor));
     SetBitsColor(DestBits, ColorBitmap.Width, ColorBitmap.Height, CX, CY,
       Color1);
   end;
 BitBlt(Canvas.Handle, X, Y, ColorBitmap.Width, ColorBitmap.Height, DestDC, 0,
   0, SRCCOPY);

 // УДАЛЕНИЕ!
 DeleteObject(DestBitmap);
 DeleteObject(DestDC);
 Dispose(ColorBits);
 Dispose(MaskBits);
 Result := True;
end;



Страницы: 1 вся ветка

Форум: "Media";
Текущий архив: 2007.03.25;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.042 c
15-1172489465
boriskb
2007-02-26 14:31
2007.03.25
США И Великобритания нашли в Ираке то, что искали


5-1150456960
mazur_r
2006-06-16 15:22
2007.03.25
Доступ к выпадающей части СomboBox


15-1172485912
Slimer
2007-02-26 13:31
2007.03.25
Плохо работает с компа на телек


2-1172746478
Mashenka_84
2007-03-01 13:54
2007.03.25
создание файла


9-1145910748
Sinistral
2006-04-25 00:32
2007.03.25
Работа с TCanvas





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