Delphi图像编程学习笔记

TGraphic是一个抽象类,TBitMap,TMetaFile,TICon等是它的子类。

TPicture是TGraphic的容器,可以显示或引用TGraphic的子类。

使用层次:TImage包含TPicture包含TGraphic(TBitMap,TMetaFile,TICon等)。

TBitMap,TMetaFile,TICon等包含有Canvas,但TGraphic不包含Canvas。

TPicture的方法一般都是调用TGraphic相应同名方法来实现的。

动态创建子类:

TGraphicClass = class of TGraphic;

…

var
  g: TGraphic;
begin
  g := TGraphicClass(TBitmap).Create; //动态匹配类型.如果TGraphicClass(xx).Create的参数xx为一个对象,则xx需要写成TGraphicClass(xx.ClassType).Create

  try
    g.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'k.bmp');
    Image1.Picture.Graphic := g;
  finally
    FreeAndNil(g);
  end;
end;
一般不用TCanvas.Pixels,因为速度太慢,颜色也可能会失真,为了快速操作像素,可以使用TBitmap.Scanline。
TCanvas的Handle为HDC类型。

图像可粗分为两大类:位映像图形和向量图形

对于复杂的的颜色,要经过两步才能在显示。

某个像素点

    |

颜色编号(多位表示,比如16位色模式中,颜色的编号可以是0~15间的任一个值,颜色编号需要4位才能表达,所以16色模式叫”4比特“模式)

    |

调色板

BMP文件资料:

BMP文件结构:

1.BITMAPFILEHEADER(BMP文件头) (占14字节)

typedef struct tagBITMAPFILEHEADER
{
WORD bfType; // 位图文件的类型,必须为“BM”
DWORD bfSize; // 位图文件的大小,以字节为单位
WORD bfReserved1; // 位图文件保留字,必须为0
WORD bfReserved2; // 位图文件保留字,必须为0
DWORD bfOffBits; // 位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位
} BITMAPFILEHEADER;该结构占据14个字节。

2.BITMAPINFOHEADER(BMP文件信息头) (占40字节)

typedef struct tagBITMAPINFOHEADER{
DWORD biSize; // 本结构所占用字节数
LONG biWidth; // 位图的宽度,以像素为单位
LONG biHeight; // 位图的高度,以像素为单位
WORD biPlanes; // 目标设备的平面数不清,必须为1
WORD biBitCount// 每个像素所需的位数,必须是1(双色), 4(16色),8(256色)或24(真彩色)之一
DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
DWORD biSizeImage; // 位图的大小,以字节为单位
LONG biXPelsPerMeter; // 位图水平分辨率,每米像素数
LONG biYPelsPerMeter; // 位图垂直分辨率,每米像素数
DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数
DWORD biClrImportant;// 位图显示过程中重要的颜色数
} BITMAPINFOHEADER;该结构占据40个字节。

3.RGBQUAD(BMP文件调色版)(占4字节)(24位色无此结构体)

颜色信息包含图像所用到的颜色表,显示图像时需用到这个颜色表来生成调色板,但如果图像为真彩色,既图像的每个像素用24个比特来表示,文件中就没有这一块信息,也就不需要操作调色板。不为24位色时,BMP文件会包括“图像颜色数(就是BITMAPINFOHEADER里的biBitCount)”个的本结构体。如为256色,则会有256个本机构体。

24位色有2的24次方色,也就是16777216色。

注意:RGBQUAD数据结构中,增加了一个保留字段rgbReserved,它不代表任何颜色,必须取固定的值为 “0”,同时,RGBQUAD结构中定义的颜色值中,红色、绿色和蓝色的排列顺序与一般真彩色图像文件的颜色数据排列顺序恰好相反,既:若某个位图中的一个像素点的颜色的描述为“00,00,ff,00”,则表示该点为红色,而不是蓝色。

4.BITMAPDATA(BMP文件数据)

typedef struct tagRGBQUAD {
BYTErgbBlue;// 蓝色的亮度(值范围为0-255)
BYTErgbGreen; // 绿色的亮度(值范围为0-255)
BYTErgbRed; // 红色的亮度(值范围为0-255)
BYTErgbReserved;// 保留,必须为0
} RGBQUAD;

文件中的数据块表示图像的相应的像素值,需要注意的是:图像的像素值在文件中的存放顺序为从左到右,从下到上,也就是说,在BMP文件中首先存放的是图像的最后一行像素,最后才存储图像的第一行像素,但对与同一行的像素,则是按照先左边后右边的的顺序存储的。

BMP是以连续行的形式存储的,但是图像是以相反的的方顺序存储的,即文件读出来的第一行是图像的最后一行,图像数据是从左下角到右上角的顺序排列的,和我们通常使用的X,Y坐标是一致的,即X坐标向右,y坐标向左。

^ y坐标

|

|

|

|______________>x坐标

如果窗体或控件等有DoubleBuffered属性并将其设置成true则可以减少闪烁.

注意:

1) BMP文件每行像素位数必须为32的整数倍,如果每行位数不到32位的整数倍,则以0填充。

2) BMP文件还规定每行的字节数必须为4的整数倍。

根据以上两点,可得出图像字节数的计算公式(单位:字节,排除BitmapFileHeader和BitmapInforHeader占用的字节数):((biWidth * biBitCount + 31) div 32) * 4 *biHeight,公式可优化为((biWidth * biBitCount + 31) shr 5 ) shl 2 * biHeight,或者更简化为):((biWidth * biBitCount + 31) div 8)  *biHeight

其中“(biWidth * biBitCount + 31) div 32”是为了保证上面第一条(公式的关键技巧在+31上),此部分得到的的是每行有多少个4字节。* 4可得到每行有多少字节,再 * biHeight就可以得到图像部分的字节数

其实32位和4字节为一个概念,1,2点是一个意思。

原文地址:https://www.cnblogs.com/cxp2009/p/2249731.html