グレースケールの画像をもとにマスク処理をして
その濃度に合わせて透明処理をして
AとBの2つの画像を合成したいと考えています。
白黒2値の画像をもとにマスク処理をして
AとBの2つの画像を合成することはできます。
グレースケールのピクセルを1つずつ調べて
その値によって合成していく方法もありかとは思いましたが、
大きな画像になると時間がかかります。
よい方法がないかと探してみましたが、
見つけることができませんでした。
環境は、WindowsXP+Delphi5です。
Vistaでも可能な方法であれば幸甚です。
新しいバージョンならできるということであればできる
ということでも結構です。
よろしくご教授ください。
nappaさん:
> グレースケールの画像をもとにマスク処理をして
> その濃度に合わせて透明処理をして
> AとBの2つの画像を合成したいと考えています。
>
> グレースケールのピクセルを1つずつ調べて
> その値によって合成していく方法もありかとは思いましたが、
> 大きな画像になると時間がかかります。
> よい方法がないかと探してみましたが、
> 見つけることができませんでした。
いわゆる「アルファブレンド」処理ですね。 下記にポイントを記します。
1.まず絶対に必要なのが、TCanvas.Pixels[] プロパティを使わない
ことです。 TBitMap.ScanLine プロパティを使ってください。
2.もうすでに TBitMap.ScanLine プロパティを使っているのでしたら、
1ピクセルあたりの処理にかかっている時間を調べてください。 10
[μs]もかかっているようでしたら、アルゴリズムを見直す価値が
ありそうです。
3.1ピクセルあたり0.1[μs]以下の時間しかかかっておらず、さらに
早くしたいということですと、OpenGL を使った手法というのがあります。
これは OpenGL のテクスチャマッピング関数を使い、複数枚の画像を重ね
合わせる手法です。 できることは限られ、またシステムが特異な挙動を
するリスクが生じます(※)が、相当早くなると思います。
※:OpenGL ユニットは、CPUの浮動小数点演算ユニット(FPU)の
フラグを書き換え、浮動小数点例外を抑止します。 そのため浮動
小数点例外を利用しているプログラムが正しく動作しなくなることが
あるのです。
4.それでも遅いということでしたら、並列処理の出番です。 プログラムを
マルチスレッド化し、複数のCPUコアを持つハイエンドのPCで処理を
行わせれば、4~8倍の処理速度が得られるかもしれません(手前味噌
ですが、これが弊社の本業です)。
5.4の代わりに、特殊な画像処理ハードウェアを使う手もあります。 しかし
コストがかかるので、単にアルファブレンドだけに使うのはもったいない
気もします。 最後の手段としてご検討ください。
――――――――――――――――――――――――――――――――――――
株式会社イマジオム 代表取締役 高木太郎
〒316-0024 茨城県 日立市 水木町 1-11-10
電話:0294-28-0147
ファクシミリ:0294-28-0148
電子メール:tarou_...@imageom.co.jp
ホームページ:http://www.imageom.co.jp/
アルファブレンド合成の方法自体が 分からないのかな?
AlphaBlendを含まない画像にAlphaBlendを含む画像を描画
AB := AlphaBlendRow[X];
R2 := SaveRow[X].Red ;
G2 := SaveRow[X].Green ;
B2 := SaveRow[X].Blue ;
R1 := BitmapRow[X].Red ;
G1 := BitmapRow[X].Green;
B1 := BitmapRow[X].Blue ;
SaveRow[X].Red := ( (R1 - R2) * AB div 255 + R2);
SaveRow[X].Green := ( (G1 - G2) * AB div 255 + G2);
SaveRow[X].Blue := ( (B1 - B2) * AB div 255 + B2);
AlphaBlendを含む画像にAlphaBlendを含む画像を描画
AB2 := LayerAlphaBlendRow[X];
if AB2 <> 0 then
begin
AB1 := AlphaBlendRow[X];
AB3 := (AB1 + AB2) - AB1 * AB2 div 255;
R1 := BitmapRow[X].Red ;
G1 := BitmapRow[X].Green;
B1 := BitmapRow[X].Blue ;
R2 := LayerRow[X].Red ;
G2 := LayerRow[X].Green ;
B2 := LayerRow[X].Blue ;
BitmapRow[X].Red := Set255( (R2 * AB2 + R1 * AB1 * (255 - AB2) div 255)
div AB3);
BitmapRow[X].Green := Set255( (G2 * AB2 + G1 * AB1 * (255 - AB2) div 255)
div AB3);
BitmapRow[X].Blue := Set255( (B2 * AB2 + B1 * AB1 * (255 - AB2) div 255)
div AB3);
AlphaBlendRow[X] := AB3;
end;
------------------------------
http://khe00221.image.coocan.jp/
------------------------------
> アルファブレンド合成の方法自体が 分からないのかな?
はい。
難しいことはわからないので、
つぎのような手順をイメージしておりました。
(1)画像データを指定
aBitmap:='AAA.BMP';
(2)その画像へのマスク画像を指定
※Mask.BMPはグレースケール画像になっている
aBitmap.Mask:='Mask.BMP';
(3)背景データ(BBB.BMP)にaBitmapを描画すると
指定したマスク画像によって半透明処理される
私には手に負えるレベルではないようですが
よい知恵がありましたらご教授願えれば幸いです。
90074 で分かってもらえなかったようなので・・・・
ABitmap (24bit画像データ) を AlphaBlendBitmap (AlphaBlend 8bitビットマップ)
を考慮して BBitmap(24bit画像データ) に描画する。
ABitmap と BBitmapは同じサイズとする
(*) BBitmap に AlphaBlend を含んだ画像の場合これはで出来ません
type
TRGB = packed record
Blue : Byte;
Green : Byte;
Red : Byte;
end;
PRGBArray = ^TRGBarray;
TRGBArray = array[0..0] of TRGB;
var
AlphaBlendRow : pArrayByte;
ABitmaoRow,BBitmapRow : pRGBArray;
X,Y,AB,R1,R2,G1,G2,B1,B2 : Integer;
begin
for Y :=0 to BBitmap.Height -1 do
begin
ABitmapRow := ABitmap.Scanline[Y];
AlphaBlendRow := AlphaBlendBitmap.Scanline[Y];
BBitmapRow := BBitmap.Scanline[Y];
for X := 0 to BBitmap.Width -1 do
begin
AB := AlphaBlendRow[X];
R2 := ABitmapRow[X].Red ;
G2 := ABitmapRow[X].Green ;
B2 := ABitmapRow[X].Blue ;
R1 := BBitmapRow[X].Red ;
G1 := BBitmapRow[X].Green;
B1 := BBitmapRow[X].Blue ;
ABitmapRow[X].Red := ( (R1 - R2) * AB div 255 + R2);
ABitmapRow[X].Green := ( (G1 - G2) * AB div 255 + G2);
ABitmapRow[X].Blue := ( (B1 - B2) * AB div 255 + B2);
end;
end;
end;
(*) 手書きなのでチェックはしていません
------------------------------
http://khe00221.image.coocan.jp/
------------------------------
----- Original Message -----
From: "Hiroyuki Nakano" <na...@kisnet.or.jp>
以下のコードで合成すると Celeron 3GB で 5msec 程度ですね。
1200 X 1000pixel 換算でで 140msec (1秒間に7枚程度)
参考になれば幸いです。
var
x, y: Integer;
gb, bm1, bm2, bm3: TBitmap; // gb: グレイスケールビットマップ pf8bit
// bm1, bm2: 合成元画像 pf24bit
// bm3: 合成先画像 pf24bit
// 全て 240 X 180 pixel
pByteGS: ^Byte;
pByte1, pByte2, pByte3: ^Byte;
alpha: Integer;
:
:
bm3 := TBitmap.Create;
bm3.PixelFormat := pf24bit;
bm3.Width := gb.Width;
bm3.Height := gb.Height;
for y := 0 to gb.Height - 1 do
begin
pByteGS := gb.Scanline[y];
pByte1 := bm1.Scanline[y];
pByte2 := bm2.Scanline[y];
pByte3 := bm3.Scanline[y];
for x := 0 to gb.Width -1 do
begin
alpha := pByteGS^;
pByte3^ := pByte1^ * alpha div 255 + pByte2^ * (255 - alpha) div 255;
Inc(pByte1); Inc(pByte2); Inc(pByte3);
pByte3^ := pByte1^ * alpha div 255 + pByte2^ * (255 - alpha) div 255;
Inc(pByte1); Inc(pByte2); Inc(pByte3);
pByte3^ := pByte1^ * alpha div 255 + pByte2^ * (255 - alpha) div 255;
Inc(pByte1); Inc(pByte2); Inc(pByte3);
Inc(pByteGS);
end;
end;
Quoting Hiroyuki Nakano <na...@kisnet.or.jp>:
----------
(株)ブレーン 中村拓男
> 中村@ブレーンです。
>
> 以下のコードで合成すると Celeron 3GB で 5msec 程度ですね。
> 1200 X 1000pixel 換算でで 140msec (1秒間に7枚程度)
> 参考になれば幸いです。
誤りがありました。Celeron 3GHz ですね(^^; もうしわけない。
----------
(株)ブレーン 中村拓男
貴重なコードをありがとうございました。
理解できるレベルではありませんが、
いただいたコードをもとに試してみたいと思います。
Quoting mori kohta <kmo...@yahoo.co.jp>:
> (1) COMオブジェクトについて学べる書籍・HPはないか(英語でも構いません)。
やっぱりこれだと思います。
「Delphi COM Programming」
http://www.amazon.com/Delphi-COM-Programming-Eric-Harmon/dp/1578702216
こいつのオートメーションに関する解説は秀逸です。
#日本のAmazon での価格は恐ろしく高額ですね。
> (2) WordのVBAでできることと、COMによる連携で出来ることに、
> 差はどれほどあるのか。特に、「ページ設定・書式設定・目次作成・
> 索引作成」などの可否について。
VBA自身COMで動作しているので、基本的にはできることの差は無いはずです。
各論は良く知らないので、マクロ記録等で VBA のソースを Word に吐かせて
みてください。VBA のソースは COM に機械的に変換できます。
手での操作を VBA/COM で100% 実現できるわけではなかったと思います。
----------
(株)ブレーン 中村拓男
> (2) WordのVBAでできることと、COMによる連携で出来ることに、差はどれほどあるのか。特に、「ページ設定・書式設定・目次作成・索引作成」などの可否について。
あなたのしたいことは、多分どちらでもできるでしょう。特に、オートメーショ
ンの部分は、そっくりなコードになるはずです。最も大きな差異は、Basicで書
くか、Pascalで書くかということだと思います。
> (1) COMオブジェクトについて学べる書籍・HPはないか(英語でも構いません)。
Word Objectのマニュアルならば、Wordに付属している筈です。少なくとも、Word2002には付いていま
す。オンラインマニュアルの、
<Microsoft Wordのヘルプ>
-<プログラミング情報>
-<Microsoft Word Visual Basic リファレンス>
以下です。
MSDN Onlineなら、以下のURLです。
http://msdn2.microsoft.com/en-us/library/bb244391.aspx
COM全般についての参考書ですと、"Inside Ole2", "Inside COM", "Essential
COM"などの名著があるのですが、翻訳版はみな絶版のようです。
--
qs2...@inter7.jp <qs2...@inter7.jp>
おそレスですが、表題どおりのことを以前HPに書きました。
参考になれば幸いです。
http://junki.lix.jp/delphigr/079MaskedOverlay2.htm
------------------------
junki junki@yahoo.co.jp
> おそレスですが、表題どおりのことを以前HPに書きました。
> 参考になれば幸いです。
>
> http://junki.lix.jp/delphigr/079MaskedOverlay2.htm
まさにこのとおりのことがやりたかったのです。
junkiさんのページは以前から知っており
参考にしておりましたが、
この部分は見落としておりました。
感謝、感謝です。