Показать сообщение отдельно
  #4  
Старый 14.07.2007, 00:18
Аватар для 4kusNick
4kusNick 4kusNick вне форума
Местный
 
Регистрация: 06.09.2006
Адрес: Россия, Санкт-Петербург
Сообщения: 444
Репутация: 550
По умолчанию

или

Код:
Код:
function RotateBitmap(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;
__________________
THE CRACKER IS OUT THERE
Ответить с цитированием