Home > Back-end >  The VCL TBitmap patch
The VCL TBitmap patch

Time:11-04

Preliminary realizes the rotating (arbitrary Angle, clockwise/counterclockwise), fixed Angle rotation (90180270 degrees clockwise/counterclockwise), flip, mirror, and other functions, converting speed can also,
There may be some BUGs, have time to test the,

 

{the VCL TBitmap Helper}
{Supplemental methods to TBitmap for supporting}
{the rotate, flip, mirror, etc.}
{version 0.01}
{written by DG, 2020-03-14}

The unit Vcl. Graphics. BitmapHelper;

Interface

USES the Vcl. Graphics;

Type
TDirection=(dir90 dir180, dir270);

TBitmapHelper=class helper for Vcl. Graphics. TBitmap
Procedure Rotate (Rads: single; Clockwise: Boolean=false;
AdjustSize: Boolean=true; BkColor: TColor=clWhite); The phrase ";
Procedure Rotate (Direction: TDirection; Clockwise: Boolean=false); The phrase ";
Procedure Flip. The inline.
Procedure Mirror; The inline.
Procedure FlipAndMirror; The inline.
end;

Implementation

USES System. Classes, WinApi. Windows;

//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
//TBitmapHelper

//the function TBitmapHelper. Rotate (Rads: single; . ) references to
//following STACKOVERFLOW thread:
//https://stackoverflow.com/questions/10633400/rotate-bitmap-by-real-angle
Procedure TBitmapHelper. Rotate (Rads: single; Clockwise: Boolean=false;
AdjustSize: Boolean=true; BkColor: TColor=clWhite);
Var
C: Single;
S: Single;
Tmp: Vcl. Graphics. TBitmap;
OffsetX: Single;
OffsetY: Single;
Points: array [0.. 2] of TPoint;
The begin
If not Clockwise then//counterclockwise
The begin
Rads:=Frac (Rads/PI * PI);
If Rads & lt; 0 then
Rads:=PI * 2 + Rads
The else
Rads:=PI * 2 - Rads;
end;

C:=Cos (Rads);
S:=Sin (Rads);
Tmp:=the Vcl. Graphics. TBitmap. Create;
Try
Tmp. TransparentColor:=the Self. The TransparentColor;
Tmp. TransparentMode:=Self. TransparentMode;
Tmp. Transparent:=Self. Transparent;
Tmp. Canvas. Brush. Color:=BkColor;

If AdjustSize then
The begin
Tmp. Width:=Round (Self. Width * Abs (C) + Self in Height * Abs (S));
Tmp. Height:=Round (Self. Width * Abs (S) + Self in Height * Abs (C));
OffsetX:=(Tmp) Width - Self) Width * C + Self in Height * S)/2;
OffsetY=(Tmp) Height - Self) Width * S - Self. The Height * C)/2;
End
The else
The begin
Tmp. Width:=the Self. The Width;
Tmp. Height:=Self. Height;
OffsetX:=(Self. Width - Self. Width * C + Self in Height * S)/2;
OffsetY=(Self. Height - Self. Width * S - Self. The Height * C)/2;
end;

Points [0]. X:=Round (OffsetX);
Points [0]. Y:=Round (OffsetY);
Points. [1] : X=Round (OffsetX + Self. Width * C);
Points [1]. Y:=Round (OffsetY + Self. Width * S);
Points [2]. X:=Round (OffsetX - Self. Height * S);
Points [2]. Y:=Round (OffsetY + Self. Height * C);
PlgBlt (Tmp) Canvas) Handle, Points,
Self. Canvas. Handle, 0, 0, the Self. The Width of the Self. The Height,
0, 0, 0);
The Self. The Assign (Tmp);
The finally
Tmp. Free;
end;
end;

{$POINTERMATH ON}
Procedure __RotateBitmap90 (var ABitmap: Vcl. Graphics. TBitmap; Clockwise: Boolean=false);
Type
TPtrMultiplex=record
In case the integer of
1: (P1: PByte);
2: (P2: PWord);
3: (P3: PRGBTriple);
4: (P4: PCardinal);
end;
Var
Tmp: Vcl. Graphics. TBitmap;
BMP: WinApi. Windows. BITMAP;
PixelSize: integer;
SrcLineSize DestLineSize: integer;
Src to Dest: pointer;
PSrc, PDest: TPtrMultiplex;
I, j: integer;
The begin
If not Assigned (ABitmap) or ABitmap. Empty then the exit;

Tmp:=the Vcl. Graphics. TBitmap. Create;
Tmp. TransparentColor:=ABitmap. TransparentColor;
Tmp. TransparentMode:=ABitmap. TransparentMode;
Tmp. Transparent:=ABitmap. Transparent;

If ABitmap. PixelFormat in [pfDevice pf1bit, pf4bit, pfCustom] then
The begin
If ABitmap. PixelFormat=pfDevice then
Tmp. PixelFormat:=pf32bit
The else
Tmp. PixelFormat:=pf8bit;
Tmp. SetSize (ABitmap. Width, ABitmap. Height);
Tmp. Canvas. The Draw (0, 0, ABitmap);
ABitmap. Assign (Tmp);
End
The else
Tmp. PixelFormat:=ABitmap. PixelFormat;
Tmp. SetSize (ABitmap. Height, ABitmap. Width);

If ABitmap. PixelFormat=pf8bit then
SelectPalette (Tmp) Canvas) Handle, ABitmap. The Palette, false);
GetObject (ABitmap. Handle, sizeof (BMP), @ BMP);
If BMP. BmBitsPixel & gt; 8 then=
The begin
PixelSize:=(BMP. BmBitsPixel + 7) div 8;
SrcLineSize:=BMP. BmWidthBytes;
Src:=BMP. BmBits;
GetObject (Tmp) Handle, sizeof (BMP), @ BMP);
DestLineSize:=BMP. BmWidthBytes;
Dest:=BMP. BmBits;

Case PixelSize of
1:
The begin
PSrc. P1:=Src;
If Clockwise, then
For I:=0 to ABitmap. Do Height - 1
The begin
PDest. P1:=Dest;
For j:=0 to ABitmap. Do Width - 1
The begin
nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
  • Related