2012-02-07 43 views
8

Si tengo un TBitmap y quiero obtener una imagen recortada de este mapa de bits, ¿puedo realizar la operación de recorte "en su lugar"? p.ej. si tengo un mapa de bits que es 800x600, ¿cómo puedo reducirlo (recortarlo) para que contenga la imagen de 600x400 en el centro, es decir, el TBitmap resultante es 600x400 y consiste en el rectángulo delimitado por (100, 100) y (700 , 500) en la imagen original?Delphi: ¿cómo recorto un mapa de bits "en su lugar"?

¿Tengo que pasar por otro mapa de bits o puedo hacer esta operación dentro del mapa de bits original?

Respuesta

20

Usted puede utilizar la función BitBlt

probar este código.

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; 

y se puede utilizar de esta manera

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; 

Si desea utilizar el mismo mapa de bits, prueba esta versión de la función

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; 

y el uso de esta forma

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

Gracias por eso. ¿Hay alguna manera simple de lograr esto sin necesidad de un segundo mapa de bits? De la misma manera que la rutina 'Move' en Delphi maneja la superposición de origen y destino, ¿existe un equivalente bidimensional? – rossmcm

+0

Puede usar Mover con la propiedad ScanLine de TBitmap, pero tendrá que calcular el tamaño de bytes de los píxeles según BitsPerPixel –

+0

, compruebe la segunda opción, esto solo usa un mapa de bits. – RRUZ

4

Sé que tiene su Ya acepté la respuesta, pero desde que escribí mi versión (que usa VCL wrapper en lugar de GDI), la publicaré aquí en lugar de simplemente descartarla.

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; 
Cuestiones relacionadas