从bmp文件中读取某点的颜色值, 随手写的, 也许有错, 不过思路还是可以看懂的:
type
TBmInfo = packed record
InfoHead: TBitmapInfoHeader;
ColorTbl: array [0..255] of TRGBQuad;
end;
function ReadPixelFromFile(AFileName: string; X, Y: Integer): TColor;
const
Bits: array [0..7] of Byte = ($80, $40, $20, $10, $8, $4, $2, $1);
var
FHead: TBitmapFileHeader; // bmp文件头
BmInfo: TBmInfo; // bmp图片头, 包含配色表
Offset: Int64; // x,y对应文件中的偏移
Fid: Integer; // 文件句柄
Len: Integer; // 每行占用字节数
XOff: Integer; // x所处字节离行首偏移量
Dt: array [0..3] of Byte; // 读取到的一个点的数据, 最长4字节
begin
if not FileExists(AFileName) then
begin
result := clNone;
exit;
end;
Fid := FileOpen(AFileName, fmOpenRead);
FileRead(Fid, FHead, sizeof(FHead));
FileRead(Fid, BmInfo, sizeof(BmInfo));
{计算x, y点在文件中的起始位置}
Len := BytesPerScanline(bminfo.InfoHead.biWidth, bminfo.InfoHead.biBitCount, 32);
XOff := x * bminfo.InfoHead.biBitCount div 8;
if BmInfo.InfoHead.biHeight < 0 then // 倒置的bmp格式, 0, 0点对应图片左上角
offset := FHead.bfOffBits + y * Len + XOff
else // 正常bmp格式, 0,0对应图片左下角
offset := FHead.bfOffBits+ (BmInfo.InfoHead.biHeight - y - 1) * Len + XOff;
{读取颜色信息}
FileSeek(Fid, offset, 0);
FileRead(Fid, Dt, (bminfo.InfoHead.biBitCount + 7) div 8); // 根据图片分辨率读取1~4字节
FileClose(Fid);
{转换颜色信息->TColor}
case bminfo.InfoHead.biBitCount of
1: // 单色
if Dt[0] and Bits[x mod 8] = 0 then
with bminfo.ColorTbl[0] do
result := RGB(rgbRed, rgbGreen, rgbBlue)
else
with bminfo.ColorTbl[1] do
result := RGB(rgbRed, rgbGreen, rgbBlue);
4: // 16色
with bminfo.ColorTbl[Dt[0] shr (4 * (1 - x mod 2)) and $F] do
result := RGB(rgbRed, rgbGreen, rgbBlue);
8: // 256色
with bminfo.ColorTbl[Dt[0]] do
result := RGB(rgbRed, rgbGreen, rgbBlue);
16: // 16位色, 每种颜色5bit
result := RGB(Dt[0] shr 2 and $1F, (Dt[0] and 3) shl 3 + (Dt[1] shr 5) and $1F, Dt[1] and $1F);
24, 32: // 真彩
result := RGB(Dt[2], Dt[1], Dt[0]);
end;
end;