BitMapを結合させるには?

解決


Jun2013  2014-01-06 04:39:06  No: 45806

Windows8,DelphiXE5(Update2),FireMonkeyでテストしています。
2つのBitMapを結合してひとつにしようと以下を実行させましたが、
できたものは、BitMapになっていないようで、ペイントでみたら
真っ黒です。2つのBitMapは同じサイズです。

procedure TForm1.Button3Click(Sender: TObject);
const
  SRC_FILE = '1.bmp';
  SRC2_FILE = '2.bmp';
var
  B,B2: TBitmap;
  SrcRect, DstRect: TRectF;
begin
  B := TBitmap.Create(0, 0);
  B2 := TBitmap.Create(0, 0);
  B.LoadFromFile(SRC_FILE);
  B2.LoadFromFile(SRC2_FILE);
  B.Canvas.BeginScene;
  try
    B.Width := B.Width+B2.Width;
    SrcRect := RectF(0, 0, B2.Width, B2.Height);
    DstRect := RectF(B.Width, 0,B.Width+B2.Width, B.Height);
    B.Canvas.DrawBitmap(B2, SrcRect, DstRect, 1);
  finally
    B.Canvas.EndScene;
    B.SaveToFile('Nbit.bmp');
    B.Free;
    B2.Free;
  end;
end;

DrawBitmapの使い方が誤っているのでしょうか?
ご存じの方お教え願いませんでしょうか。


けど  2014-01-06 06:13:13  No: 45807

要は「B.Width := B.Width+B2.Width;」の時点で幅が変わってるからではないかな
今時の書き方知らないんでちょっと変えたけど
var
  B,B2: TBitmap;
  OriginalWidth:integer;
begin
  B := TBitmap.Create;
  B2 := TBitmap.Create;
  try
    B.LoadFromFile(SRC_FILE);
    B2.LoadFromFile(SRC2_FILE);
    OriginalWidth:=B.Width;
    B.Width := B.Width+B2.Width;
    B.Canvas.CopyRect(Rect(OriginalWidth, 0,OriginalWidth+B2.Width, B.Height),B2.Canvas,Rect(0, 0, B2.Width, B2.Height));
  finally
    B.SaveToFile('e:\1\a.bmp');
    B.Free;
    B2.Free;
  end;
end;


Jun2013  2014-01-06 09:01:50  No: 45808

けどさん、早速の返答ありがとうございます。
CopyRectはFireMonkeyではなくなっているようで、エラーになります。
何か準備をすれば、CopyRectは可能なのでしょうか。

2つの画像を横並びにして一つにしたいのですが、VCLの時は
    r.Width := a.Width  + b.Width;
    r.Canvas.Draw(0,0,a);
    r.Canvas.Draw(a.Width,0,b);
などとして、aとbをくっつけてrにしていました。


けど  2014-01-07 08:06:54  No: 45809

いあ、だから Jun2013 さんが最初に出されたものを
私の書いた「OriginalWidth」のある行だけ変えて試してみてくださいよ
RectF の定義すら調べていませんがソースを見る限りこんなことをやってるんだろうと思っただけです
また、Draw に当たるものも FireMonkey にあるのかも知れませんが私は知りません


Jun2013  2014-01-07 10:04:30  No: 45810

失礼しました。ロジックとして誤っていますね。
修正して試しましたが、結果として同じで期待したものには
なりませんでした。
それで、サイズ変更方法に誤りがあるかもと思い,DrawBitmapを実行せずに、
サイズの変更をしてすぐに戻すことをしました。
    B.Width := B.Width+B2.Width;
    B.Width := B.Width-B2.Width;
とすると元のサイズの画像になると期待しますが、画像として
壊れた状態(ペイントで真っ黒)になります。
サイズの変更方法か順序が違うのでしょうね。


DEKO  2014-01-07 18:15:39  No: 45811

ワーク用の TBitmap を用意すれば解決すると思います。

procedure CombineBitmap(const Src1, Src2, Dst: TFileName);
var
  bmpSrc1, bmpSrc2, bmpDst: TBitmap;
  rectSrc1, rectSrc2, rectDst: TRectF;
begin
  bmpSrc1 := TBitmap.Create(0, 0);
  bmpSrc2 := TBitmap.Create(0, 0);
  try
    bmpSrc1.LoadFromFile(Src1);
    bmpSrc2.LoadFromFile(Src2);
    rectSrc1 := RectF(0, 0, bmpSrc1.Width, bmpSrc1.Height);
    rectSrc2 := RectF(0, 0, bmpSrc2.Width, bmpSrc2.Height);
    rectDst  := rectSrc2;
    OffsetRect(rectDst, bmpSrc1.Width, 0);
    bmpDst := TBitmap.Create(bmpSrc1.Width + bmpSrc2.Width, bmpSrc1.Height);
    try
      bmpDst.Canvas.BeginScene;
      bmpDst.Canvas.DrawBitmap(bmpSrc1, rectSrc1, rectSrc1, 1);
      bmpDst.Canvas.DrawBitmap(bmpSrc2, rectSrc2, rectDst , 1);
      bmpDst.Canvas.EndScene;
      bmpDst.SaveToFile(Dst);
    finally
      bmpDst.Free;
    end;
  finally
    bmpSrc1.Free;
    bmpSrc2.Free;
  end;
end;


けど  2014-01-08 07:42:58  No: 45812

DEKOさんどもです
普通はそうしますよね
提示されたソースが結構新鮮で「へぇそんなこと出来るんだ」と感心したもので


Jun2013  2014-01-08 18:33:53  No: 45813

DEKOさん、どもさん  ありがとうございます。
できるようになりました。
OffsetRectの使い方とか勉強になりました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加