2012-02-07 18 views
8

Eğer bir TBitmap'ım varsa ve bu bitmap'ten kırpılmış bir görüntü elde etmek istiyorsanız, kırpma işlemini "yerinde" yapabilir miyim? Örneğin. 800x600 olan bir bitmapim varsa, merkezde 600x400 görüntüyü, yani elde edilen TBitmap'ın 600x400 olduğunu ve (100, 100) ve (700) tarafından sınırlanan dikdörtgenden oluşmasını nasıl sağlayabilirim (kırpma) , 500) orijinal görüntüde mi?Delphi - "yerinde" bir bitmap'i nasıl kırpırım?

Başka bir bitmap yoluyla gitmem gerekiyor mu yoksa bu işlem özgün bitmap içinde yapılabilir mi?

cevap

20

bu kodu deneyin BitBlt fonksiyonunu

kullanabilirsiniz. Aynı bit eşlem kullanmak istiyorsanız

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; 

ve bu şekilde kullanabilirsiniz

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; 

, fonksiyonu

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; 

bu sürümünü denemek Ve bu şekilde kullanmak

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

Bunun için teşekkürler. İkinci bir bitmap'e gerek kalmadan bunu gerçekleştirmenin basit bir yolu var mı? Delphi'deki 'Move' rutini ile aynı şekilde örtüşen kaynak ve hedefleri ele alırken, iki boyutlu bir eşdeğer var mıdır? – rossmcm

+0

TBitmap'in ScanLine özelliği ile birlikte taşıyabilirsiniz, ancak BitsPerPixel –

+0

'a bağlı olarak piksellerin bayt büyüklüğünü hesaplamanız gerekir, bu seçenek yalnızca bir bitmap kullanır. – RRUZ

4

Zaten kabul edilmiş bir cevap, ama benim sürümü (GDI çağrısı yerine VCL sarıcı kullanır) yazdığımdan beri, onu fırlatmak yerine buraya yayınlayacağım.

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;