首页  编辑  

位图的旋转

Tags: /超级猛料/Picture.图形图像编程/图片处理/   Date Created:

]、。·ˉˇ¨〃々—~‖…’”〕〉》」』〗】∶!"'),.:;?]` http://www.efg2.com/lab/ImageProcessing/RotateScanline.htm

CONST

 MaxPixelCount = 32768;

TYPE

 TRGBTripleArray = ARRAY[0..MaxPixelCount-1] OF TRGBTriple;

 pRGBTripleArray = ^TRGBTripleArray;

...

// "Simple" approach. For pixel (i,j), use "reverse" rotation to find

// where the rotated pixel must have been before the rotation.

// Don't bother with center of pixel adjustment.

// Assumes input BitmapOriginal has PixelFormat = pf24bit.

FUNCTION RotateBitmapMethod1 (CONST BitmapOriginal: TBitmap;

 CONST iRotationAxis, jRotationAxis: INTEGER;

 CONST AngleOfRotation: DOUBLE  {radians} ): TBitmap;

 VAR

   cosTheta   : EXTENDED;

   i          : INTEGER;

   iOriginal  : INTEGER;

   iPrime     : INTEGER;

   j          : INTEGER;

   jOriginal  : INTEGER;

   jPrime     : INTEGER;

   RowOriginal: pRGBTripleArray;

   RowRotated : pRGBTRipleArray;

   sinTheta   : EXTENDED;  

BEGIN

 // The size of BitmapRotated is the same as BitmapOriginal. PixelFormat

 // must also match since 24-bit GBR triplets are assumed in ScanLine.

 RESULT := TBitmap.Create;

 RESULT.Width  := BitmapOriginal.Width;

 RESULT.Height := BitmapOriginal.Height;

 RESULT.PixelFormat := pf24bit; // Force this

 // Get SIN and COS in single call from math library

 sincos(AngleOfRotation, sinTheta, cosTheta);

 // If no math library, then use this:

 // sinTheta := SIN(AngleOfRotation);

 // cosTheta := COS(AngleOfRotation);

 // Step through each row of rotated image.

 FOR j := RESULT.Height-1 DOWNTO 0 DO

 BEGIN

   RowRotated := RESULT.Scanline[j];

   jPrime := j - jRotationAxis;

   FOR i := RESULT.Width-1 DOWNTO 0 DO

   BEGIN

     iPrime := i - iRotationAxis;

     iOriginal := iRotationAxis + ROUND(iPrime * CosTheta - jPrime * sinTheta);

     jOriginal := jRotationAxis + ROUND(iPrime * sinTheta + jPrime * cosTheta);

     // Make sure (iOriginal, jOriginal) is in BitmapOriginal. If not,

     // assign blue color to corner points.

     IF (iOriginal >= 0) AND (iOriginal <= BitmapOriginal.Width-1) AND

         (jOriginal >= 0) AND (jOriginal <= BitmapOriginal.Height-1)

     THEN BEGIN

       // Assign pixel from rotated space to current pixel in BitmapRotated

       RowOriginal := BitmapOriginal.Scanline[jOriginal];

       RowRotated[i] := RowOriginal[iOriginal]

     END

     ELSE BEGIN

       RowRotated[i].rgbtBlue := 255; // assign "corner" color

       RowRotated[i].rgbtGreen := 0;

       RowRotated[i].rgbtRed := 0

    END

   END

 END

END {RotateBitmapMethod1};