Delphi - объектно-ориентированный язык программирования, разработанный компанией Borland в 1995 году. Он основан на языке программирования Pascal, но имеет более расширенные возможности и добавлены новые функции.
Delphi является интегрированной средой разработки (IDE), которая позволяет разрабатывать программное обеспечение для различных платформ, включая Windows, macOS, Android и iOS. Delphi достигает многоплатформенности с помощью...
functionRotateBitmap(var
hDIB: HGlobal; radang: Double; clrBack: TColor): Boolean; // (c) Copyright original C Code: Code Guru var
lpDIBBits: Pointer; lpbi, hDIBResult: PBitmapInfoHeader; bpp, nColors, nWidth, nHeight, nRowBytes: Integer; cosine, sine: Double; x1, y1, x2, y2, x3, y3, minx, miny, maxx, maxy, ti, x, y, w, h: Integer; nResultRowBytes, nHeaderSize: Integer; i, len: longint; lpDIBBitsResult: Pointer; dwBackColor: DWORD; PtrClr: PRGBQuad; RbackClr, GBackClr, BBackClr: Word; sourcex, sourcey: Integer; mask: Byte; PtrByte: PByte; dwpixel: DWORD; PtrDWord: PDWord; hDIBResInfo: HGlobal; begin
; // Get source bitmap info lpbi := PBitmapInfoHeader(GlobalLock(hdIB)); nHeaderSize := lpbi^.biSize + lpbi^.biClrUsed * SizeOf(TRGBQUAD); lpDIBBits := Pointer(Longint(lpbi) + nHeaderSize); bpp := lpbi^.biBitCount; // Bits per pixel ncolors := lpbi^.biClrUsed; // Already computed when bitmap was loaded nWidth := lpbi^.biWidth; nHeight := lpbi^.biHeight; nRowBytes := ((((nWidth * bpp) + 31) and
(not
31)) shr
3); // Compute the cosine and sine only once cosine := cos(radang); sine := sin(radang); // Compute dimensions of the resulting bitmap // First get the coordinates of the 3 corners other than origin x1 := ceil(-nHeight * sine); // Originally floor at all places y1 := ceil(nHeight * cosine); x2 := ceil(nWidth * cosine - nHeight * sine); y2 := ceil(nHeight * cosine + nWidth * sine); x3 := ceil(nWidth * cosine); y3 := ceil(nWidth * sine); minx := min(0, min(x1, min(x2, x3))); miny := min(0, min(y1, min(y2, y3))); maxx := max(0, max(x1, max(x2, x3)));// added max(0, maxy := max(0, max(y1, max(y2, y3)));// added max(0, w := maxx - minx; h := maxy - miny; // Create a DIB to hold the result nResultRowBytes := ((((w * bpp) + 31) and
(not
31)) div
8); len := nResultRowBytes * h; hDIBResInfo := GlobalAlloc(GMEM_MOVEABLE, len + nHeaderSize); if
hDIBResInfo = 0 then
begin
Result := False; Exit; end
; hDIBResult := PBitmapInfoHeader(GlobalLock(hDIBResInfo)); // Initialize the header information CopyMemory(hDIBResult, lpbi, nHeaderSize); //BITMAPINFO &bmInfoResult = *(LPBITMAPINFO)hDIBResult ; hDIBResult^.biWidth := w; hDIBResult^.biHeight := h; hDIBResult^.biSizeImage := len; lpDIBBitsResult := Pointer(Longint(hDIBResult) + nHeaderSize); // Get the back color value (index) ZeroMemory(lpDIBBitsResult, len); case
bpp of
1: begin
//Monochrome if
(clrBack = RGB(255, 255, 255)) then
FillMemory(lpDIBBitsResult, len, $ff); end
; 4, 8: begin
//Search the color table PtrClr := PRGBQuad(Longint(lpbi) + lpbi^.bisize); RBackClr := GetRValue(clrBack); GBackClr := GetGValue(clrBack); BBackClr := GetBValue(clrBack); for
i := 0 to
nColors - 1 do
// Color table starts with index 0 begin
if
(PtrClr^.rgbBlue = BBackClr) and
(PtrClr^.rgbGreen = GBackClr) and
(PtrClr^.rgbRed = RBackClr) then
begin
if
(bpp = 4) then
//if(bpp==4) i = i | i<<4; ti := i or
(i shl
4) else
ti := i; FillMemory(lpDIBBitsResult, ti, len); break; end
; Inc(PtrClr); end
;// If not match found the color remains black end
; 16: begin
(* When the Compression field is
set
to
BI_BITFIELDS, Windows 95 supports only the following 16bpp color masks: A 5-5-5 16-bit image, where the blue mask is
$001F, the green mask is
$03E0, and
the red mask is
$7C00; and
a 5-6-5 16-bit image, where the blue mask is
$001F, the green mask is
$07E0, and
the red mask is
$F800. *) PtrClr := PRGBQuad(Longint(lpbi) + lpbi^.bisize); if
(PtrClr^.rgbRed = $7c00) then
// Check the Red mask begin
// Bitmap is RGB555 dwBackColor := ((GetRValue(clrBack) shr
3) shl
10) + ((GetRValue(clrBack) shr
3) shl
5) + (GetBValue(clrBack) shr
3); end
else
begin
// Bitmap is RGB565 dwBackColor := ((GetRValue(clrBack) shr
3) shl
11) + ((GetRValue(clrBack) shr
2) shl
5) + (GetBValue(clrBack) shr
3); end
; end
; 24, 32: begin
dwBackColor := ((GetRValue(clrBack)) shl
16) or
((GetGValue(clrBack)) shl
8) or
((GetBValue(clrBack))); end
; end
; // Now do the actual rotating - a pixel at a time // Computing the destination point for each source point // will leave a few pixels that do not get covered // So we use a reverse transform - e.i. compute the source point // for each destination point for
y := 0 to
h - 1 do
begin
for
x := 0 to
w - 1 do
begin
sourcex := floor((x + minx) * cosine + (y + miny) * sine); sourcey := floor((y + miny) * cosine - (x + minx) * sine); if
((sourcex >= 0) and
(sourcex < nWidth) and
(sourcey >= 0) and
(sourcey < nHeight)) then
begin
// Set the destination pixel case
bpp of
1: begin
//Monochrome mask := PByte(Longint(lpDIBBits) + nRowBytes * sourcey + (sourcex div
8))^ and
($80 shr
(sourcex mod
8)); if
mask <> 0 then
mask := $80 shr
(x mod
8); PtrByte := PByte(Longint(lpDIBBitsResult) + nResultRowBytes * y + (x div
8)); PtrByte^ := PtrByte^ and
(not
($80 shr
(x mod
8))); PtrByte^ := PtrByte^ or
mask; end
; 4: begin
if
((sourcex and
1) <> 0) then
mask := $0f else
mask := $f0; mask := PByte(Longint(lpDIBBits) + nRowBytes * sourcey + (sourcex div
2))^ and
mask; if
((sourcex and
1) <> (x and
1)) then
begin
if
(mask and
$f0) <> 0 then
mask := (mask shr
4) else
mask := (mask shl
4); end
; PtrByte := PByte(Longint(lpDIBBitsResult) + nResultRowBytes * y + (x div
2)); if
((x and
1) <> 0) then
PtrByte^ := PtrByte^ and
(not
$0f) else
PtrByte^ := PtrByte^ and
(not
$f0); PtrByte^ := PtrByte^ or
Mask; end
; 8: begin
mask := PByte(Longint(lpDIBBits) + nRowBytes * sourcey + sourcex)^; PtrByte := PByte(Longint(lpDIBBitsResult) + nResultRowBytes * y + x); PtrByte^ := mask; end
; 16: begin
dwPixel := PDWord(Longint(lpDIBBits) + nRowBytes * sourcey + sourcex * 2)^; PtrDword := PDWord(Longint(lpDIBBitsResult) + nResultRowBytes * y + x * 2); PtrDword^ := Word(dwpixel); end
; 24: begin
dwPixel := PDWord(Longint(lpDIBBits) + nRowBytes * sourcey + sourcex * 3)^ and
$ffffff; PtrDword := PDWord(Longint(lpDIBBitsResult) + nResultRowBytes * y + x * 3); PtrDword^ := PtrDword^ or
dwPixel; end
; 32: begin
dwPixel := PDWord(Longint(lpDIBBits) + nRowBytes * sourcey + sourcex * 4)^; PtrDword := PDWord(Longint(lpDIBBitsResult) + nResultRowBytes * y + x * 4); PtrDword^ := dwpixel; end
; end
; // Case end
else
begin
// Draw the background color. The background color // has already been drawn for 8 bits per pixel and less case
bpp of
16: begin
PtrDWord := PDWord(Longint(lpDIBBitsResult) + nResultRowBytes * y + x * 2); PtrDword^ := Word(dwBackColor); end
; 24: begin
PtrDWord := PDWord(Longint(lpDIBBitsResult) + nResultRowBytes * y + x * 3); PtrDword^ := PtrDword^ or
dwBackColor; end
; 32: begin
PtrDWord := PDWord(Longint(lpDIBBitsResult) + nResultRowBytes * y + x * 4); PtrDword^ := dwBackColor; end
; end
; end
; end
; end
; GlobalUnLock(hDIBResInfo); GlobalUnLock(hDIB); GlobalFree(hDIB); hDIB := hDIBResInfo; Result := True; end
;