16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"RE:256色マスク指定、ビットマップをコピー"
この発言は #00340 河邦 正 さんの透過率を指定してビットマップをコピーする に対するコメントです
この発言に対し以下のコメントが寄せられています
#00827 河邦 正 さん Re: ビットマップを半透明で描画する
河邦 正 さん、の透過率サンプルをちょっと改造させて頂きましたので…
αチャネルとなるグレースケールビットマップを指定して、ビットマップをコピ
ーします。αチャネル=黒の部分はコピー先ビットマップがそのまま、αチャネ
ル=白の部分はコピー元ビットマップのピクセルが描画され、中間では濃さに応
じてブレンドされます。
procedure CopyBitmapWith256scaleMask(
bmpDst: TBitmap; // コピー先ビットマップ
pointDst: TPoint; // コピーする場所の左上の座標
bmpSrc: TBitmap; // コピー元ビットマップ
bmpMsk: TBitmap; // αチャネルとなるグレースケールビットマップ
);
キャラクタを背景にふんわりと重ねたい、不定形&半透明の部品を置きたい、
等の場合に使います。足部分をグラデーションで黒く塗ったαチャネルを用意す
れば、簡単に幽霊が描けます(笑)
αチャネルは、PhotoShop使う人なら分かると思いますが、キャラクタの透明
部分を書き出せば簡単に出来ます。
なお速度的に、アニメーションは無理です。
「魔法の効果みたいなのを出したい」場合にはやっぱりDirectXでないと無理
ですねぇ(^^;。
procedure CopyBitmapWith256scaleMask(bmpDst: TBitmap;
pointDst: TPoint; bmpSrc: TBitmap; bmpMsk: TBitmap );
var
rectDst, rectSrc, rectTmp: TRect;
x, y: Integer;
prgbDst, prgbSrc: PRGBQuad;
pMsk: PByteArray; //マスクは8bitのBitMapなので。
begin
// 重なっている(コピーする)部分を計算する
rectSrc := RECT(0, 0, bmpSrc.Width, bmpSrc.Height);
OffsetRect(rectSrc, pointDst.x, pointDst.y);
rectDst := RECT(0, 0, bmpDst.Width, bmpDst.Height);
IntersectRect(rectTmp, rectDst, rectSrc);
// 重なっている部分がある場合には、コピー処理する
if(rectTmp.Left < rectTmp.Right)and
(rectTmp.Top < rectTmp.Bottom)then
begin
// ピクセルあたりのデータサイズを DWORD に揃える
bmpDst.PixelFormat := pf32Bit;
bmpSrc.PixelFormat := pf32Bit;
// 重なった領域のデータからコピー元とコピー先の領域を設定する
rectDst := rectTmp;
OffsetRect(rectTmp, -pointDst.x, -pointDst.y);
rectSrc := rectTmp;
for y := rectSrc.Top to rectSrc.Bottom - 1 do
begin
// コピー元のラインを取得する
prgbDst := bmpDst.ScanLine[y + pointDst.y];
Inc(prgbDst, rectDst.Left);
// コピー先のラインを取得する
prgbSrc := bmpSrc.ScanLine[y];
Inc(prgbSrc, rectSrc.Left);
// マスクのラインを取得する
pMsk := bmpMsk.ScanLine[y];
for x := rectSrc.Left to rectSrc.Right - 1 do
begin
if (pMsk[x] > 0)then
//マスクがまっ黒以外の部分を処理。>16 位でも。
begin
prgbDst^.rgbRed := (
(prgbDst^.rgbRed * (255 - pMsk[x])) +
(prgbSrc^.rgbRed * pMsk[x])) div 255;
prgbDst^.rgbGreen := (
(prgbDst^.rgbGreen *(255 - pMsk[x])) +
(prgbSrc^.rgbGreen * pMsk[x]))div 255;
prgbDst^.rgbBlue := (
(prgbDst^.rgbBlue * (255 - pMsk[x])) +
(prgbSrc^.rgbBlue * pMsk[x]))div 255;
end;
Inc(prgbDst);
Inc(prgbSrc);
end;
end;
end;
end;
//使用例
procedure TForm1.Button1Click(Sender: TObject);
var
bmpDst, bmpSrc: TBitmap;
bmpMsk: TBitmap;
begin
bmpDst := TBitmap.Create;
bmpSrc := TBitmap.Create;
bmpMsk := TBitmap.Create;
bmpDst.LoadFromFile('c:\My Documents\haikei.bmp');
bmpSrc.LoadFromFile('c:\My Documents\character01.bmp');
bmpMsk.LoadFromFile('c:\My Documents\character01_mask01.bmp');
CopyBitmapWith256scaleMask(bmpDst, POINT(100, 0), bmpSrc, bmpMsk);
// ビットマップをフォームに描画する
Canvas.Draw(0,0, bmpDst);
bmpDst.Free;
bmpSrc.Free;
bmpMsk.Free;
end;
ありがとうございます>河邦さん
http://www.st.rim.or.jp/~toyozou/
99/01/16(土) 23:11 とよぞう(PXW07530)
Original document by とよぞう 氏 ID:(PXW07530)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|