unit Graphics;
{$I switches.inc}
interface
uses
Classes, SysUtils, Windows, FreeBitmap, FreeImage;
type
TPixelFormat = (pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit, pfCustom);
TColor = -$7FFFFFFF-1..$7FFFFFFF;
TCanvas = class
private
FImage : TFreeBitmap;
function GetPixel(x, y: Integer): TColor;
procedure SetPixel(x, y: Integer; const Value: TColor);
public
Constructor Create(const bmp : TFreeBitmap);
property Pixels[x,y : Integer] : TColor read GetPixel write SetPixel;
end;
TBitmap = class
private
FCanvas : TCanvas;
function GetHeight: Integer;
function GetWidth: Integer;
procedure SetHeight(const Value: Integer);
procedure SetWidth(const Value: Integer);
function GetPixelFormat: TPixelFormat;
procedure SetPixelFormat(const Value: TPixelFormat);
function GetScanLine(Line: Integer): Pointer;
protected
FImage : TFreeBitmap;
public
Constructor Create;
Destructor Destroy; override;
Procedure LoadFromStream(const str : TStream);
Procedure LoadFromFile(const f : String);
Procedure SaveToFile(const f : String); virtual;
Procedure Assign(const src : TBitmap);
property Width : Integer read GetWidth write SetWidth;
property Height : Integer read GetHeight write SetHeight;
property PixelFormat : TPixelFormat read GetPixelFormat write SetPixelFormat;
property ScanLine[Line : Integer] : Pointer read GetScanLine;
property Canvas : TCanvas read FCanvas;
end;
implementation
{ TBitmap }
type
TRealRGB = packed record
rgbRed: Byte;
rgbGreen: Byte;
rgbBlue: Byte;
rgbReserved: Byte;
end;
procedure TBitmap.Assign(const src: TBitmap);
begin
FImage.Assign(src.FImage);
FCanvas.FImage := FImage;
end;
constructor TBitmap.Create;
begin
FImage := TFreeBitmap.Create( FIF_BMP, 4, 4, 24);
FCanvas := TCanvas.Create(FImage);
end;
destructor TBitmap.Destroy;
begin
FCanvas.Free;
FImage.Free;
inherited;
end;
function TBitmap.GetHeight: Integer;
begin
Result := FImage.GetHeight;
end;
function TBitmap.GetPixelFormat: TPixelFormat;
begin
Result := pf24bit;
case FImage.GetBitsPerPixel of
1 : Result := pf1bit;
4 : Result := pf4bit;
8 : Result := pf8bit;
15 : Result := pf15bit;
16 : Result := pf16bit;
24 : Result := pf24bit;
32 : Result := pf32bit;
end;
end;
function TBitmap.GetScanLine(Line: Integer): Pointer;
begin
Result := FImage.GetScanLine(Height-1-Line);
end;
function TBitmap.GetWidth: Integer;
begin
Result := FImage.GetWidth;
end;
procedure TBitmap.LoadFromFile(const f: String);
begin
FreeAndNil(FCanvas);
FreeAndNil(FImage);
FImage := TFreeBitmap.Create;
FImage.Load(f);
FCanvas := TCanvas.Create(FImage);
end;
procedure TBitmap.LoadFromStream(const str: TStream);
begin
FreeAndNil(FCanvas);
FreeAndNil(FImage);
FImage := TFreeBitmap.Create;
FImage.LoadFromStream(str);
FCanvas := TCanvas.Create(FImage);
end;
procedure TBitmap.SaveToFile(const f: String);
begin
FImage.Save(f);
end;
procedure TBitmap.SetHeight(const Value: Integer);
begin
if Value <> Height then begin
FImage.Rescale( Width, Value, FILTER_BILINEAR);
end;
end;
procedure TBitmap.SetPixelFormat(const Value: TPixelFormat);
begin
if Value <> PixelFormat then begin
case Value of
pf4bit : FImage.ConvertTo4Bits;
pf8bit : FImage.ConvertTo8Bits;
pf15bit : FImage.ConvertTo16Bits555;
pf16bit : FImage.ConvertTo16Bits565;
pf24bit : FImage.ConvertTo24Bits;
pf32bit : FImage.ConvertTo32Bits;
end;
end;
end;
procedure TBitmap.SetWidth(const Value: Integer);
begin
if Value <> Width then begin
FImage.Rescale( Value, Height, FILTER_BILINEAR);
end;
end;
{ TCanvas }
constructor TCanvas.Create(const bmp: TFreeBitmap);
begin
FImage := bmp;
end;
function TCanvas.GetPixel(x, y: Integer): TColor;
var
pix : TRGBQuad;
begin
FImage.GetPixelColor( x, FImage.GetHeight-1-y, @pix);
Result := TColor(pix);
end;
procedure TCanvas.SetPixel(x, y: Integer; const Value: TColor);
var
pixRGB : TRealRGB;
pixBGR : TRGBQuad;
begin
Move( Value, pixRGB, SizeOf(pixRGB));
pixBGR.rgbRed := pixRGB.rgbRed;
pixBGR.rgbGreen := pixRGB.rgbGreen;
pixBGR.rgbBlue := pixRGB.rgbBlue;
pixBGR.rgbReserved := pixRGB.rgbReserved;
FImage.SetPixelColor( x, FImage.GetHeight-1-y, @pixBGR);
end;
end.