Форум: "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.037 c