如果我有一个TBitmap,想要从这个位图中获取裁剪后的图像,能否在原位进行裁剪操作?例如,如果我有一个800x600的位图,如何缩小(裁剪)它,使其包含中心的600x400图像,即生成的TBitmap是600x400,并由原始图像中(100,100)和(700,500)所限定的矩形组成?
需要通过另一个位图吗,还是可以在原始位图内完成这个操作?
需要通过另一个位图吗,还是可以在原始位图内完成这个操作?
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;
我知道你已经有了接受的答案,但是因为我写了我的版本(使用VCL包装器而不是GDI调用),所以我会在这里发布它,而不是把它扔掉。
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;