2012-02-07 6 views
8

私はTBitmapを持っていて、このビットマップから切り抜かれたイメージを取得したいのですが、 "その場で"切り抜き操作を実行できますか?例えば800x600のビットマップを持っている場合、600x400イメージを中央に含むように、つまり結果のTBitmapが600x400で、(100,100)と(700)で囲まれた四角形、500)?Delphi - ビットマップを「インプレース」でどのようにトリミングするのですか?

別のビットマップを使用する必要がありますか、またはこの操作を元のビットマップ内で行うことはできますか?

答えて

20

あなたはこのコードを試してみてくださいBitBlt機能

を使用することができます。あなたは同じビットマップを使用したい場合は

procedure CropBitmap(InBitmap, OutBitMap : TBitmap; X, Y, W, H :Integer); 
begin 
    OutBitMap.PixelFormat := InBitmap.PixelFormat; 
    OutBitMap.Width := W; 
    OutBitMap.Height := H; 
    BitBlt(OutBitMap.Canvas.Handle, 0, 0, W, H, InBitmap.Canvas.Handle, X, Y, SRCCOPY); 
end; 

、あなたがこの方法で使用することができますが

Var 
    Bmp : TBitmap; 
begin 
    Bmp:=TBitmap.Create; 
    try 
    CropBitmap(Image1.Picture.Bitmap, Bmp, 10,0, 150, 150); 
    //do something with the cropped image 
    //Bmp.SaveToFile('Foo.bmp'); 
    finally 
    Bmp.Free; 
    end; 
end; 

、機能

procedure CropBitmap(InBitmap : TBitmap; X, Y, W, H :Integer); 
begin 
    BitBlt(InBitmap.Canvas.Handle, 0, 0, W, H, InBitmap.Canvas.Handle, X, Y, SRCCOPY); 
    InBitmap.Width :=W; 
    InBitmap.Height:=H; 
end; 

のこのバージョンを試してみて、このような方法で使用

Var 
Bmp : TBitmap; 
begin 
    Bmp:=Image1.Picture.Bitmap; 
    CropBitmap(Bmp, 10,0, 150, 150); 
    //do somehting with the Bmp 
    Image1.Picture.Assign(Bmp); 
end; 
+0

ありがとうございます。 2番目のビットマップを必要とせずにこれを達成する簡単な方法はありますか? Delphiの 'Move'ルーチンと同じように、ソースとデスティネーションが重なって扱われますが、2次元の同等物はありますか? – rossmcm

+0

TBitmapのScanLineプロパティでMoveを使用できますが、BitsPerPixelに応じてピクセルのバイトサイズを計算する必要があります –

+0

これは1つのビットマップのみを使用する2番目のオプションを確認します。 – RRUZ

4

私は自分のバージョン(GDIコールの代わりにVCLラッパーを使用しています)を書いて以来、私はそれを投げ捨てる代わりにここに投稿します。

procedure TForm1.FormClick(Sender: TObject); 
var 
    Source, Dest: TRect; 
begin 
    Source := Image1.Picture.Bitmap.Canvas.ClipRect; 
    { desired rectangle obtained by collapsing the original one by 2*2 times } 
    InflateRect(Source, -(Image1.Picture.Bitmap.Width div 4), -(Image1.Picture.Bitmap.Height div 4)); 
    Dest := Source; 
    OffsetRect(Dest, -Dest.Left, -Dest.Top); 
    { NB: raster data is preserved during the operation, so there is not need to have 2 bitmaps } 
    Image1.Picture.Bitmap.Canvas.CopyRect(Dest, Image1.Picture.Bitmap.Canvas, Source); 
    { and finally "truncate" the canvas } 
    Image1.Picture.Bitmap.Width := Dest.Right; 
    Image1.Picture.Bitmap.Height := Dest.Bottom; 
end; 
関連する問題