unit Graphics2; interface uses Windows,SysUtils,Graphics,Math; const MaxPixelCount = 32768; type pRGBTripleArray = ^TRGBTripleArray; TRGBTripleArray = ARRAY[0..MaxPixelCount-1] OF TRGBTriple; //二值化 procedure bmp2valus(bmp:TBitmap;Threshold:Byte=128); //bmp旋转任意角度 function RotateBitmap(const BitmapOriginal: TBitmap; const iRotationAxis, jRotationAxis: Integer; const AngleOfRotation: Double): TBitmap; implementation //二值化 procedure bmp2valus(bmp:TBitmap;Threshold: Byte=128); var p: PByteArray; Gray, x, y: Integer; begin for y := 0 to Bmp.Height - 1 do begin p := Bmp.scanline[y]; for x := 0 to Bmp.Width - 1 do begin //一个象素点三个字节 Gray := Round(p[x * 3 + 2] * 0.3 + p[x * 3 + 1] * 0.59 + p[x* 3] * 0.11); if gray >Threshold then //全局阀值128 begin p[x * 3] := 255; p[x * 3 + 1] := 255; p[x * 3 + 2] := 255; end else begin p[x * 3] := 0; p[x * 3 + 1] := 0; p[x * 3 + 2] := 0; end; end; end; end; //bmp旋转任意角度 function RotateBitmap(const BitmapOriginal: TBitmap; const iRotationAxis, jRotationAxis: Integer; const AngleOfRotation: Double): TBitmap; var cosTheta : EXTENDED; i : INTEGER; iOriginal : INTEGER; iPrime : INTEGER; j : INTEGER; jOriginal : INTEGER; jPrime : INTEGER; RowOriginal: pRGBTripleArray; RowRotated : pRGBTRipleArray; sinTheta : EXTENDED; Angle: DOUBLE; 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 //弧度角转换 Angle := (AngleOfRotation / 180) * pi; // Get SIN and COS in single call from math library sincos(Angle, 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 := 255; RowRotated[i].rgbtRed := 255; END END END end; end.