📄 dib.pas
字号:
unit DIB;
interface
{$INCLUDE DelphiXcfg.inc}
uses
Windows, SysUtils, Classes, Graphics, Controls;
type
TRGBQuads = array[0..255] of TRGBQuad;
TPaletteEntries = array[0..255] of TPaletteEntry;
PBGR = ^TBGR;
TBGR = packed record
B, G, R: Byte;
end;
PArrayBGR = ^TArrayBGR;
TArrayBGR = array[0..10000] of TBGR;
PArrayByte = ^TArrayByte;
TArrayByte = array[0..10000] of Byte;
PArrayWord = ^TArrayWord;
TArrayWord = array[0..10000] of Word;
PArrayDWord = ^TArrayDWord;
TArrayDWord = array[0..10000] of DWord;
{ TDIB }
TDIBPixelFormat = record
RBitMask, GBitMask, BBitMask: DWORD;
RBitCount, GBitCount, BBitCount: DWORD;
RShift, GShift, BShift: DWORD;
RBitCount2, GBitCount2, BBitCount2: DWORD;
end;
TDIBSharedImage = class(TSharedImage)
private
FBitCount: Integer;
FBitmapInfo: PBitmapInfo;
FBitmapInfoSize: Integer;
FChangePalette: Boolean;
FColorTable: TRGBQuads;
FColorTablePos: Integer;
FCompressed: Boolean;
FDC: THandle;
FHandle: THandle;
FHeight: Integer;
FMemoryImage: Boolean;
FNextLine: Integer;
FOldHandle: THandle;
FPalette: HPalette;
FPaletteCount: Integer;
FPBits: Pointer;
FPixelFormat: TDIBPixelFormat;
FSize: Integer;
FTopPBits: Pointer;
FWidth: Integer;
FWidthBytes: Integer;
constructor Create;
procedure NewImage(AWidth, AHeight, ABitCount: Integer;
const PixelFormat: TDIBPixelFormat; const ColorTable: TRGBQuads; MemoryImage, Compressed: Boolean);
procedure Duplicate(Source: TDIBSharedImage; MemoryImage: Boolean);
procedure Compress(Source: TDIBSharedImage);
procedure Decompress(Source: TDIBSharedImage; MemoryImage: Boolean);
procedure ReadData(Stream: TStream; MemoryImage: Boolean);
function GetPalette: THandle;
procedure SetColorTable(const Value: TRGBQuads);
protected
procedure FreeHandle; override;
public
destructor Destroy; override;
end;
TDIB = class(TGraphic)
private
FCanvas: TCanvas;
FImage: TDIBSharedImage;
FProgressName: string;
FProgressOldY: DWORD;
FProgressOldTime: DWORD;
FProgressOld: DWORD;
FProgressY: DWORD;
{ For speed-up }
FBitCount: Integer;
FHeight: Integer;
FNextLine: Integer;
FNowPixelFormat: TDIBPixelFormat;
FPBits: Pointer;
FSize: Integer;
FTopPBits: Pointer;
FWidth: Integer;
FWidthBytes: Integer;
procedure AllocHandle;
procedure CanvasChanging(Sender: TObject);
procedure Changing(MemoryImage: Boolean);
procedure ConvertBitCount(ABitCount: Integer);
function GetBitmapInfo: PBitmapInfo;
function GetBitmapInfoSize: Integer;
function GetCanvas: TCanvas;
function GetHandle: THandle;
function GetPaletteCount: Integer;
function GetPixel(X, Y: Integer): DWORD;
function GetPBits: Pointer;
function GetPBitsReadOnly: Pointer;
function GetScanLine(Y: Integer): Pointer;
function GetScanLineReadOnly(Y: Integer): Pointer;
function GetTopPBits: Pointer;
function GetTopPBitsReadOnly: Pointer;
procedure SetBitCount(Value: Integer);
procedure SetImage(Value: TDIBSharedImage);
procedure SetNowPixelFormat(const Value: TDIBPixelFormat);
procedure SetPixel(X, Y: Integer; Value: DWORD);
procedure StartProgress(const Name: string);
procedure EndProgress;
procedure UpdateProgress(PercentY: Integer);
protected
procedure DefineProperties(Filer: TFiler); override;
procedure Draw(ACanvas: TCanvas; const Rect: TRect); override;
function GetEmpty: Boolean; override;
function GetHeight: Integer; override;
function GetPalette: HPalette; override;
function GetWidth: Integer; override;
procedure ReadData(Stream: TStream); override;
procedure SetHeight(Value: Integer); override;
procedure SetPalette(Value: HPalette); override;
procedure SetWidth(Value: Integer); override;
procedure WriteData(Stream: TStream); override;
public
ColorTable: TRGBQuads;
PixelFormat: TDIBPixelFormat;
constructor Create; override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure Clear;
procedure Compress;
procedure Decompress;
procedure FreeHandle;
procedure LoadFromClipboardFormat(AFormat: Word; AData: THandle;
APalette: HPALETTE); override;
procedure LoadFromStream(Stream: TStream); override;
procedure SaveToClipboardFormat(var AFormat: Word; var AData: THandle;
var APalette: HPALETTE); override;
procedure SaveToStream(Stream: TStream); override;
procedure SetSize(AWidth, AHeight, ABitCount: Integer);
procedure UpdatePalette;
{ Special effect }
procedure Blur(ABitCount: Integer; Radius: Integer);
procedure Greyscale(ABitCount: Integer);
procedure Mirror(MirrorX, MirrorY: Boolean);
procedure Negative;
property BitCount: Integer read FBitCount write SetBitCount;
property BitmapInfo: PBitmapInfo read GetBitmapInfo;
property BitmapInfoSize: Integer read GetBitmapInfoSize;
property Canvas: TCanvas read GetCanvas;
property Handle: THandle read GetHandle;
property Height: Integer read FHeight write SetHeight;
property NextLine: Integer read FNextLine;
property NowPixelFormat: TDIBPixelFormat read FNowPixelFormat write SetNowPixelFormat;
property PaletteCount: Integer read GetPaletteCount;
property PBits: Pointer read GetPBits;
property PBitsReadOnly: Pointer read GetPBitsReadOnly;
property Pixels[X, Y: Integer]: DWORD read GetPixel write SetPixel;
property ScanLine[Y: Integer]: Pointer read GetScanLine;
property ScanLineReadOnly[Y: Integer]: Pointer read GetScanLineReadOnly;
property Size: Integer read FSize;
property TopPBits: Pointer read GetTopPBits;
property TopPBitsReadOnly: Pointer read GetTopPBitsReadOnly;
property Width: Integer read FWidth write SetWidth;
property WidthBytes: Integer read FWidthBytes;
end;
TDIBitmap = class(TDIB) end;
{ TCustomDXDIB }
TCustomDXDIB = class(TComponent)
private
FDIB: TDIB;
procedure SetDIB(Value: TDIB);
public
constructor Create(AOnwer: TComponent); override;
destructor Destroy; override;
property DIB: TDIB read FDIB write SetDIB;
end;
{ TDXDIB }
TDXDIB = class(TCustomDXDIB)
published
property DIB;
end;
{ TCustomDXPaintBox }
TCustomDXPaintBox = class(TGraphicControl)
private
FAutoStretch: Boolean;
FCenter: Boolean;
FDIB: TDIB;
FKeepAspect: Boolean;
FStretch: Boolean;
FViewWidth: Integer;
FViewHeight: Integer;
procedure SetAutoStretch(Value: Boolean);
procedure SetCenter(Value: Boolean);
procedure SetDIB(Value: TDIB);
procedure SetKeepAspect(Value: Boolean);
procedure SetStretch(Value: Boolean);
procedure SetViewWidth(Value: Integer);
procedure SetViewHeight(Value: Integer);
protected
function GetPalette: HPALETTE; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Paint; override;
property AutoStretch: Boolean read FAutoStretch write SetAutoStretch;
property Canvas;
property Center: Boolean read FCenter write SetCenter;
property DIB: TDIB read FDIB write SetDIB;
property KeepAspect: Boolean read FKeepAspect write SetKeepAspect;
property Stretch: Boolean read FStretch write SetStretch;
property ViewWidth: Integer read FViewWidth write SetViewWidth;
property ViewHeight: Integer read FViewHeight write SetViewHeight;
end;
{ TDXPaintBox }
TDXPaintBox = class(TCustomDXPaintBox)
published
{$IFDEF DelphiX_Spt4}property Anchors;{$ENDIF}
property AutoStretch;
property Center;
{$IFDEF DelphiX_Spt4}property Constraints;{$ENDIF}
property DIB;
property KeepAspect;
property Stretch;
property ViewWidth;
property ViewHeight;
property Align;
property DragCursor;
property DragMode;
property Enabled;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property Visible;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDrag;
end;
function MakeDIBPixelFormat(RBitCount, GBitCount, BBitCount: Integer): TDIBPixelFormat;
function MakeDIBPixelFormatMask(RBitMask, GBitMask, BBitMask: Integer): TDIBPixelFormat;
function pfRGB(const PixelFormat: TDIBPixelFormat; R, G, B: Byte): DWORD;
procedure pfGetRGB(const PixelFormat: TDIBPixelFormat; Color: DWORD; var R, G, B: Byte);
function pfGetRValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte;
function pfGetGValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte;
function pfGetBValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte;
function GreyscaleColorTable: TRGBQuads;
function RGBQuad(R, G, B: Byte): TRGBQuad;
function PaletteEntryToRGBQuad(const Entry: TPaletteEntry): TRGBQuad;
function PaletteEntriesToRGBQuads(const Entries: TPaletteEntries): TRGBQuads;
function RGBQuadToPaletteEntry(const RGBQuad: TRGBQuad): TPaletteEntry;
function RGBQuadsToPaletteEntries(const RGBQuads: TRGBQuads): TPaletteEntries;
implementation
uses DXConsts;
function Max(B1, B2: Integer): Integer;
begin
if B1>=B2 then Result := B1 else Result := B2;
end;
function MakeDIBPixelFormat(RBitCount, GBitCount, BBitCount: Integer): TDIBPixelFormat;
begin
Result.RBitMask := ((1 shl RBitCount)-1) shl (GBitCount+BBitCount);
Result.GBitMask := ((1 shl GBitCount)-1) shl (BBitCount);
Result.BBitMask := (1 shl BBitCount)-1;
Result.RBitCount := RBitCount;
Result.GBitCount := GBitCount;
Result.BBitCount := BBitCount;
Result.RBitCount2 := 8-RBitCount;
Result.GBitCount2 := 8-GBitCount;
Result.BBitCount2 := 8-BBitCount;
Result.RShift := (GBitCount+BBitCount)-(8-RBitCount);
Result.GShift := BBitCount-(8-GBitCount);
Result.BShift := 8-BBitCount;
end;
function MakeDIBPixelFormatMask(RBitMask, GBitMask, BBitMask: Integer): TDIBPixelFormat;
function GetBitCount(b: Integer): Integer;
var
i: Integer;
begin
i := 0;
while (i<31) and (((1 shl i) and b)=0) do Inc(i);
Result := 0;
while ((1 shl i) and b)<>0 do
begin
Inc(i);
Inc(Result);
end;
end;
begin
Result := MakeDIBPixelFormat(GetBitCount(RBitMask), GetBitCount(GBitMask),
GetBitCount(BBitMask));
end;
function pfRGB(const PixelFormat: TDIBPixelFormat; R, G, B: Byte): DWORD;
begin
with PixelFormat do
Result := ((R shl RShift) and RBitMask) or ((G shl GShift) and GBitMask) or
((B shr BShift) and BBitMask);
end;
procedure pfGetRGB(const PixelFormat: TDIBPixelFormat; Color: DWORD; var R, G, B: Byte);
begin
with PixelFormat do
begin
R := (Color and RBitMask) shr RShift;
R := R or (R shr RBitCount2);
G := (Color and GBitMask) shr GShift;
G := G or (G shr GBitCount2);
B := (Color and BBitMask) shl BShift;
B := B or (B shr BBitCount2);
end;
end;
function pfGetRValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte;
begin
with PixelFormat do
begin
Result := (Color and RBitMask) shr RShift;
Result := Result or (Result shr RBitCount);
end;
end;
function pfGetGValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte;
begin
with PixelFormat do
begin
Result := (Color and GBitMask) shr GShift;
Result := Result or (Result shr GBitCount);
end;
end;
function pfGetBValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte;
begin
with PixelFormat do
begin
Result := (Color and BBitMask) shl BShift;
Result := Result or (Result shr BBitCount);
end;
end;
function GreyscaleColorTable: TRGBQuads;
var
i: Integer;
begin
for i:=0 to 255 do
with Result[i] do
begin
rgbRed := i;
rgbGreen := i;
rgbBlue := i;
rgbReserved := 0;
end;
end;
function RGBQuad(R, G, B: Byte): TRGBQuad;
begin
with Result do
begin
rgbRed := R;
rgbGreen := G;
rgbBlue := B;
rgbReserved := 0;
end;
end;
function PaletteEntryToRGBQuad(const Entry: TPaletteEntry): TRGBQuad;
begin
with Result do
with Entry do
begin
rgbRed := peRed;
rgbGreen := peGreen;
rgbBlue := peBlue;
rgbReserved := 0;
end;
end;
function PaletteEntriesToRGBQuads(const Entries: TPaletteEntries): TRGBQuads;
var
i: Integer;
begin
for i:=0 to 255 do
Result[i] := PaletteEntryToRGBQuad(Entries[i]);
end;
function RGBQuadToPaletteEntry(const RGBQuad: TRGBQuad): TPaletteEntry;
begin
with Result do
with RGBQuad do
begin
peRed := rgbRed;
peGreen := rgbGreen;
peBlue := rgbBlue;
peFlags := 0;
end;
end;
function RGBQuadsToPaletteEntries(const RGBQuads: TRGBQuads): TPaletteEntries;
var
i: Integer;
begin
for i:=0 to 255 do
Result[i] := RGBQuadToPaletteEntry(RGBQuads[i]);
end;
{ TDIBSharedImage }
type
PLocalDIBPixelFormat = ^TLocalDIBPixelFormat;
TLocalDIBPixelFormat = packed record
RBitMask, GBitMask, BBitMask: DWORD;
end;
TPaletteItem = class(TCollectionItem)
private
ID: Integer;
Palette: HPalette;
RefCount: Integer;
ColorTable: TRGBQuads;
ColorTableCount: Integer;
destructor Destroy; override;
procedure AddRef;
procedure Release;
end;
TPaletteManager = class
private
FList: TCollection;
constructor Create;
destructor Destroy; override;
function CreatePalette(const ColorTable: TRGBQuads; ColorTableCount: Integer): HPalette;
procedure DeletePalette(var Palette: HPalette);
end;
destructor TPaletteItem.Destroy;
begin
DeleteObject(Palette);
inherited Destroy;
end;
procedure TPaletteItem.AddRef;
begin
Inc(RefCount);
end;
procedure TPaletteItem.Release;
begin
Dec(RefCount);
if RefCount<=0 then Free;
end;
constructor TPaletteManager.Create;
begin
inherited Create;
FList := TCollection.Create(TPaletteItem);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -