在用image加载bmp图片时,要使用某点的像素值,传统的做法是scanline、canvas.pixel、或者用api函数来获取。
既然image能画出bmp图片来,bmp中应该包含这个位图的像素值。来找找。果然找到了
TBitmap 的 父类是 TGraphic,
TBitmap = class(TGraphic)
private
FImage: TBitmapImage;
FCanvas: TCanvas;
FIgnorePalette: Boolean;
FMaskBitsValid: Boolean;
FMaskValid: Boolean;
FTransparentColor: TColor;
FTransparentMode: TTransparentMode;
FAlphaFormat: TAlphaFormat;
procedure Changing(Sender: TObject);
procedure CopyImage(AHandle: HBITMAP; APalette: HPALETTE; DIB: TDIBSection);
procedure DIBNeeded;
procedure FreeContext;
function GetCanvas: TCanvas;
TGraphic的第一个私有变量就是FImage, FImage: TBitmapImage;
查看 TBitmapImage
TBitmapImage = class(TSharedImage)
private
FHandle: HBITMAP; // DDB or DIB handle, used for drawing
FMaskHandle: HBITMAP; // DDB handle
FPalette: HPALETTE;
FDIBHandle: HBITMAP; // DIB handle corresponding to TDIBSection
FDIB: TDIBSection;
FSaveStream: TMemoryStream; // Save original RLE stream until image is modified
FHalftone: Boolean; // FPalette is halftone; don't write to file
{$IF DEFINED(CLR)}
FImageFormat: TImageFormat;
{$ELSE}
FOS2Format: Boolean; // Write BMP file header, color table in OS/2 format
{$IFEND}
protected
procedure FreeHandle; override;
public
destructor Destroy; override;
{$IF DEFINED(CLR)}
function GetHashCode: Integer; override;
{$IFEND}
end;
FDIB: TDIBSection;就是我需要的。
type
PDIBSection = ^TDIBSection;
{$EXTERNALSYM tagDIBSECTION}
tagDIBSECTION = packed record
dsBm: TBitmap;
dsBmih: TBitmapInfoHeader;
dsBitfields: array[0..2] of DWORD;
dshSection: THandle;
dsOffset: DWORD;
end;
TDIBSection = tagDIBSECTION;
{$EXTERNALSYM DIBSECTION}
DIBSECTION = tagDIBSECTION;
dsBm: TBitmap; 包含像素值。查看TBitmap。
PBitmap = ^TBitmap;
{$EXTERNALSYM tagBITMAP}
tagBITMAP = packed record
bmType: Longint;
bmWidth: Longint;
bmHeight: Longint;
bmWidthBytes: Longint;
bmPlanes: Word;
bmBitsPixel: Word;
bmBits: Pointer;
end;
TBitmap = tagBITMAP;
{$EXTERNALSYM BITMAP}
BITMAP = tagBITMAP;
bmBits: Pointer;中包含的就是位图的像素值了。
如何获取这个值呢?
这就涉及到如何获取类的私有变量的问题
第一步:获取FImage ,获取类的私有变量方法一
TBitmap 的 IgnorePalette 属性是公开的,我们可以访问到。FIgnorePalette = IgnorePalette,说明我们可以通过 IgnorePalette 找到 FIgnorePalette 的地址,在上两个
就是 FImage的地址了。
FImage := Pointer(@srcbmp.IgnorePalette);
dec(FImage, SizeOf(TCanvas) - 2);
第二步:获取 FDIB,获取类的私有变量方法二
TBitmapImage 类没有任何导出函数,方法一派不上用场了。
直接用地址。
FImage^ 里面存放了 TBitmapImage 类的内存起始地址
FImage^ + 4 * 4 + 8 就是 FDIB的地址了
FDIB := Pointer(FImage^ + 24);
GOOD,可以任意访问私有变量了。