把BMP图像读入到二维数组(200分属于谁)(200分)

  • 主题发起人 主题发起人 quickchop
  • 开始时间 开始时间
amukusa与cqbaobao的方法是不同的,因为每一点的象素值是用3各字节保存的,所以用字节定地
还是比较准确的,还有前提是24位图。
我一般是不管什么图,都用
bmp.pixelformat:=pf24;
转为24位的,这样比较好处理。
 
yylei,你会不会用读文件头的方法来得到rgb值。确实加上你那句就不会出错了,这是为什么。
我要强调的是amukusa(后来的那个与cqbaobao的方法是相同)
 
现在赚钱真是越来越难了,呵呵。。。

读文件头的方法已经包含在 bmp.LoadFromFile 方法里,没必要为它专门写程序;你可以参考 VCL 源码;
这也是我前面说的:
>> 另外:我认为系统既然提供的功能,我们就尽可能利用!
的意思。

amukusa 的第一个方法中的 Pixels[] 属性实际调用了 GetPixel 这个 API,
而这个 API 确实效率有问题,MS 自己也承认这一点;

所以说最好的办法就是用扫描线,尤其是 24 位图,也就是 16M 色真彩图,
因为这种位图每个象素点正好对应 3 个字节,分别代表 B, G, R(注意顺序),
而每个 Pb[x] 也代表一个字节,所以处理起来非常方便

对非 24 位图,就麻烦一些;第一,需要对每点进行一些移位操作,详细的参见:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=530544
第二,这些图还用了调色板,操作调色板这个我也不熟:(
 
算了,你们一个也不会文件头的方法。只好给各位打分了,如果有意见请反馈。
 
有几天没上,所以耽误了一下,琪是我原来做过直接读文件数据来获取数据的程序,后来发现有点麻烦,
而且找到了用scanline的方法,所以就改了。但是既然你要,我就吧我原来的方法以贴出来参考:
定义类型:
type
Theader=record
Fileheader:bitmapfileheader; //关于该类型定义按F1 delphi有说明,其实就是你开始的定义
infoHeader:bitmapinfoheader; //
end;

var
f1:file; //用于读数据;
f2:file of Theader; //用于读文件头;
myheader:Theader;

先读文件头到myheader:
assignfile(f2,$yourfilename);
reset(f2);
read(f2,myheader);
closefile(f2);
然后可根据myheader定义数组大小,或者直接定义一个1024*1024的二维数组,应该够了吧?
在读数据:
assignfile(f1,$yourfilename);
reset(f1,1); //参数跟前面是有区别的;
seek(f1,myheader.fileheader.bfOffBits); //定位到数据偏移处;
{计算每行字节数,这个比较复杂,还好当时求出了通解;}
Lwidth:=((myheader.infoheader.biWidth*myheader.infoheader.biBitCount+31) div 32)*4;
for i :=0 to header.infoHeader.biHeight-1 do
blockread(f1,Rdata,xxx); //按每一行按字节读数据
下面就是数据拆分了,最麻烦,我就不写程序了,写写基本原理:
1。 每一行的数据字节数必须要能被4整除,不足的补零;
2。 2色的一个二进制位可以表示一个像素,一个字节就有8个象素的数据;
16色的4个二进制位一个像素,一个字节有2个象素的数据;
256色最方便,一个字节一个象素数据;
24位真彩色的是4个字节一个象素数据,好像是g,b,r,00,最后一个00位保留字节。
3。以上所说的数据都是指在调色板里的索引值,除了24位真彩色,因为它没有调色板。
你需要做得就是根据颜色数,按字节拆分象素值。
 
更正一下,上面的xxx应是Lwidth
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部