16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"Re: ビットマップを半透明で描画する"
この発言は #00800 とよぞう さんのRE:256色マスク指定、ビットマップをコピー に対するコメントです
【タイトル】ビットマップを半透明で描画する
とよぞうさん、サンプルを改良していただきありがとうございます。
#800> なお速度的に、アニメーションは無理です。
透過率を 50% に固定することで、いくらか速くできます。
下記のサンプルコードの作業用ビットマップを使いまわしして、大きさと
フレームレートを制限すれば、本当に(冗談でなく)アニメーションできる
でしょう。
P5-120MHz で VGAサイズを 5コマ/秒が出ます(ライブラリに公開してあ
る BlendImage コンポーネントで検証)。整数演算が主体なので AMD-K6 系
のCPUなら 300MHz 程度で 15コマ/秒が軽く出せるのでは?
応用で 25% と 75% 固定でも、ほぼ同じ処理速度が得られるはずです。
【使用上の注意】
ディスプレイモードはフルカラーが推奨です。
TBitmap.ScanLine プロパティを使用しているため、Delphi3/C++Builder3
以上が対象になります。
// ビットマップを半透明で描画する
procedure DrawTranslucent(Canvas: TCanvas; x, y: Integer;
Graphic: TGraphic);
var
bmpBkg, bmpMix: TBitmap;
pdwMix, pdwSrc: PDWORD;
w, h, iX, iY, iLineSize: Integer;
begin
w := Graphic.Width;
h := Graphic.Height;
bmpBkg := TBitmap.Create;
bmpMix := TBitmap.Create;
// 背景をビットマップに取得する
bmpBkg.Width := w;
bmpBkg.Height := h;
bmpBkg.PixelFormat := pf24bit;
bmpBkg.Canvas.CopyRect(Rect(0, 0, w, h), Canvas,
Rect(x, y, x + w, y + h));
// 「背景+ビットマップ」をビットマップにする
bmpMix.Assign(bmpBkg);
bmpMix.Canvas.Draw(0, 0, Graphic);
//「背景」と「背景+ビットマップ」を半々に混ぜる
iLineSize := (w * 3 + 3) div sizeof(DWORD);
for iY := 0 to h - 1 do
begin
pdwMix := bmpMix.ScanLine[iY];
pdwSrc := bmpBkg.ScanLine[iY];
for iX := 0 to iLineSize - 1 do
begin
Dec(pdwMix^, (pdwMix^ shr 1)and $7f7f7f7f
- (pdwSrc^ shr 1)and $7f7f7f7f);
Inc(pdwMix);
Inc(pdwSrc);
end;
end;
// 混ぜたビットマップを描く
Canvas.Draw(x, y, bmpMix);
bmpMix.Free;
bmpBkg.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
DrawTranslucent(Canvas, 0, 0, Image1.Picture.Bitmap);
end;
//---------------------------------------------------------------------------
// ここから C++Builder ユーザー用です
void DrawTranslucent(TCanvas *Canvas, int x, int y,
Graphics::TGraphic *Graphic)
{
int w = Graphic->Width;
int h = Graphic->Height;
Graphics::TBitmap* bmpBkg = new Graphics::TBitmap;
Graphics::TBitmap* bmpMix = new Graphics::TBitmap;
// 背景をビットマップに取得する
bmpBkg->Width = w;
bmpBkg->Height = h;
bmpBkg->PixelFormat = pf24bit;
bmpBkg->Canvas->CopyRect(Rect(0, 0, w, h), Canvas,
Rect(x, y, x + w, y + h));
// 「背景+ビットマップ」をビットマップにする
bmpMix->Assign(bmpBkg);
bmpMix->Canvas->Draw(0, 0, Graphic);
//「背景」と「背景+ビットマップ」を半々に混ぜる
int iLineSize = (w * 3 + 3) / sizeof(DWORD);
for(int iY = 0; iY < h; iY++)
{
DWORD* pdwMix = (DWORD*)(bmpMix->ScanLine[iY]);
DWORD* pdwSrc = (DWORD*)(bmpBkg->ScanLine[iY]);
for(int iX = 0; iX < iLineSize; iX++)
{
*pdwMix -= ((*pdwMix >> 1) & 0x7f7f7f7f)
- ((*pdwSrc >> 1) & 0x7f7f7f7f);
pdwMix++;
pdwSrc++;
}
}
// 混ぜたビットマップを描く
Canvas->Draw(x, y, bmpMix);
delete bmpMix;
delete bmpBkg;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
DrawTranslucent(Canvas, 0, 0, Image1->Picture->Bitmap);
}
//---------------------------------------------------------------------------
1999/02/26、河邦 正(GCC02240@nifty.ne.jp)
Original document by 河邦 正 氏 ID:(GCC02240)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|