给你一段代码不过要用到GDI+你自已装一个就可以了procedure FSDither(Source, Dest: Tbitmap);type TRgb = packed record Blue: Byte; Green: Byte; Red: Byte; Filler: Byte; end; TIntegerArray = array[0..(MaxLongInt div 4) - 1] of Integer; TpIntegerArray = ^TIntegerArray;var RErr1: TpIntegerArray; { red errors } RErr2: TpIntegerArray; GErr1: TpIntegerArray; { green errors } GErr2: TpIntegerArray; BErr1: TpIntegerArray; { blue errors } BErr2: TpIntegerArray; function RGB2Color(RGB: TRgb): TColor; begin with RGB do begin Result := Blue shl 16 or Green shl 8 or Red; end; // with end; function BoundInteger(const Value: longint; const MinValue: longint; const MaxValue: longint): longint; begin Result := Value; if Result < MinValue then Result := MinValue; if Result > MaxValue then Result := MaxValue; end; function color2rgb(Color: TColor): TRgb; begin with Result do begin Red := Color and $FF; Green := (Color and $FF00) shr 8; Blue := (Color and $FF0000) shr 16; end; end; procedure AllocateErrors; var Size: longint; begin Size := Source.Width * SizeOf(Integer); GetMem(RErr1, Size); GetMem(RErr2, Size); GetMem(GErr1, Size); GetMem(GErr2, Size); GetMem(BErr1, Size); GetMem(BErr2, Size); FillChar(RErr1^, Size, 0); FillChar(RErr2^, Size, 0); FillChar(GErr1^, Size, 0); FillChar(GErr2^, Size, 0); FillChar(BErr1^, Size, 0); FillChar(BErr2^, Size, 0); end; procedure ReleaseErrors; var Size: longint; begin Size := Source.Width * SizeOf(Integer); FreeMem(RErr1, Size); FreeMem(RErr2, Size); FreeMem(GErr1, Size); FreeMem(GErr2, Size); FreeMem(BErr1, Size); FreeMem(BErr2, Size); end; procedure DitherScanLine(const LineNo: longint); var X: longint; RGB: TRgb; RErr: Integer; GErr: Integer; BErr: Integer; begin for X := 0 to (Source.Width - 1) do begin RGB := color2rgb(Source.Canvas.Pixels[X, LineNo]); RErr1^[X] := BoundInteger(RErr2^[X] + RGB.Red, 0, 255); RErr2^[X] := 0; GErr1^[X] := BoundInteger(GErr2^[X] + RGB.Green, 0, 255); GErr2^[X] := 0; BErr1^[X] := BoundInteger(BErr2^[X] + RGB.Blue, 0, 255); BErr2^[X] := 0; end; RGB.Red := RErr1^[0]; RGB.Green := GErr1^[0]; RGB.Blue := BErr1^[0]; Dest.Canvas.Pixels[0, LineNo] := RGB2Color(RGB); for X := 1 to (Source.Width - 2) do begin RGB.Red := RErr1^[X]; RGB.Green := GErr1^[X]; RGB.Blue := BErr1^[X]; { Using the Rgb property will perform the Color matching } Dest.Canvas.Pixels[X, LineNo] := RGB2Color(RGB); { get the actual Rgb value after Color matching to compute the error } RGB := color2rgb(Dest.Canvas.Pixels[X, LineNo]); { compute errors } RErr := RErr1^[X]; RErr := RErr - RGB.Red; GErr := GErr1^[X]; GErr := GErr - RGB.Green; BErr := BErr1^[X]; BErr := BErr - RGB.Blue; RErr1^[X + 1] := BoundInteger((RErr1^[X + 1] + ((RErr * 7)) div 16), 0, 255); RErr2^[X - 1] := BoundInteger((RErr2^[X - 1] + ((RErr * 3)) div 16), 0, 255); RErr2^[X] := BoundInteger((RErr2^[X] + ((RErr * 5)) div 16), 0, 255); RErr2^[X + 1] := BoundInteger((RErr2^[X + 1] + ((RErr * 1)) div 16), 0, 255); GErr1^[X + 1] := BoundInteger((GErr1^[X + 1] + ((GErr * 7)) div 16), 0, 255); GErr2^[X - 1] := BoundInteger((GErr2^[X - 1] + ((GErr * 3)) div 16), 0, 255); GErr2^[X] := BoundInteger((GErr2^[X] + ((GErr * 5)) div 16), 0, 255); GErr2^[X + 1] := BoundInteger((GErr2^[X + 1] + ((GErr * 1)) div 16), 0, 255); BErr1^[X + 1] := BoundInteger((BErr1^[X + 1] + ((BErr * 7)) div 16), 0, 255); BErr2^[X - 1] := BoundInteger((BErr2^[X - 1] + ((BErr * 3)) div 16), 0, 255); BErr2^[X] := BoundInteger((BErr2^[X] + ((BErr * 5)) div 16), 0, 255); BErr2^[X + 1] := BoundInteger((BErr2^[X + 1] + ((BErr * 1)) div 16), 0, 255); end; RGB.Red := RErr1^[Source.Width - 1]; RGB.Green := GErr1^[Source.Width - 1]; RGB.Blue := BErr1^[Source.Width - 1]; Dest.Canvas.Pixels[Source.Width - 1, LineNo] := RGB2Color(RGB); end;var Y: longint; HeightMinusOne: longint;begin AllocateErrors; try HeightMinusOne := Source.Height - 1; for Y := 0 to HeightMinusOne do begin DitherScanLine(Y); end; finally ReleaseErrors; end;end;procedure convertBmpPixelFormat(SourceBmp: TGPBitmap; PixelFormat: Integer);var Graphics: TGPGraphics; X, Y: Integer; Bitmap, tmpBit: Tbitmap; A, R, G, B: Integer; Color: TGPColor;begin Graphics := TGPGraphics.create(SourceBmp); Graphics.SetSmoothingMode(SmoothingModeHighQuality); Graphics.SetInterpolationMode(InterpolationModeHighQuality); Graphics.SetPixelOffsetMode(PixelOffsetModeHighQuality); Graphics.DrawImage(SourceBmp, 0, 0, SourceBmp.GetWidth, SourceBmp.GetHeight); Graphics.Free; Bitmap := Tbitmap.create; Bitmap.Width := SourceBmp.GetWidth; Bitmap.Height := SourceBmp.GetHeight; for X := 0 to Bitmap.Width - 1 do begin for Y := 0 to Bitmap.Height - 1 do begin SourceBmp.GetPixel(X, Y, Color); A := GetAlpha(Color); R := GetRed(Color); G := GetGreen(Color); B := GetBlue(Color); if A > 125 then A := 255 else A := 0; SourceBmp.SetPixel(X, Y, MakeColor(A, R, G, B)); end; end; Graphics := TGPGraphics.create(Bitmap.Canvas.Handle); if PixelFormat <> 32 then begin Graphics.SetInterpolationMode(InterpolationModeNearestNeighbor); Graphics.SetPixelOffsetMode(SmoothingModeHighQuality); end else begin Graphics.SetInterpolationMode(InterpolationModeHighQualityBilinear); Graphics.SetPixelOffsetMode(SmoothingModeHighQuality); end; Graphics.DrawImage(SourceBmp, 0, 0, Bitmap.Width, Bitmap.Height); Graphics.Free; tmpBit := Tbitmap.create; tmpBit.Width := Bitmap.Width; tmpBit.Height := Bitmap.Height; case PixelFormat of 8: tmpBit.PixelFormat := pf8bit; 4: tmpBit.PixelFormat := pf4bit; 1: tmpBit.PixelFormat := pf1bit; end; FSDither(Bitmap, tmpBit); { case PixelFormat of 8: BitMap.PixelFormat := pf8bit; 4: BitMap.PixelFormat := pf4bit; 1: BitMap.PixelFormat := pf1bit; end;} for X := 0 to tmpBit.Width - 1 do begin for Y := 0 to tmpBit.Height - 1 do begin SourceBmp.GetPixel(X, Y, Color); A := GetAlpha(Color); R := GetRValue(tmpBit.Canvas.Pixels[X, Y]); G := GetGValue(tmpBit.Canvas.Pixels[X, Y]); B := GetBValue(tmpBit.Canvas.Pixels[X, Y]); if A <> 0 then A := 255 else A := 0; SourceBmp.SetPixel(X, Y, MakeColor(A, R, G, B)); end; end; Bitmap.Free; tmpBit.Free;end;