目录
Bmp格式
bmp文件包含:
文件头(bitmap-file header):14个字节
位图信息头(bitmap information header):40个字节
调色板(color table):可选
位图数据(bits data):
用Ultraedit软件打开以上北极熊图片:
文件头(14 bytes)
名称 |
字节 |
内容 |
|
bfType |
2 |
BM标识 |
0x42 |
bfSize |
4 |
整个BMP文件大小 |
0x005EEC8A(6220938) |
bfReserved |
4 |
保留字 |
0x00000000 |
bfOffbits |
4 |
偏移数,即位图文件头+位图信息图+调色板大小 |
0x00000008A (138) |
文件头+位图+调色板共占138个字节
位图数据占6220938-138=6220800=1920*1080*3 字节
位图信息图(40bytes)
biSize |
4 |
位图信息头+调色板大小 |
0x0000007c |
biWidth |
4 |
图像宽度 |
0x00000780 |
biHeight |
4 |
以像素为单位说明图像的高度,同时如果为正,说明位图倒立(即数据表示从图像的左下角到右上角),如果为负说明正向 |
0x00000438 |
biPlanes |
2 |
为目标设备说明颜色平面数,总被设置为1 |
|
biBitCount |
2 |
说明比特数/像素数,值有1、2、4、8、16、24、32 |
0x0018 表明RGB共24bits |
biCompression |
4 |
说明图像的压缩类型,最常用的就是0(BI_RGB),表示不压缩 |
|
biSizeImages |
4 |
说明位图数据的大小,当用BI_RGB格式时,可以设置为0 |
0x00005eec |
biXPelsPerMeter |
4 |
表示水平分辨率,单位是像素/米,有符号整数 |
|
biYPelsPerMeter |
4 |
表示垂直分辨率,单位是像素/米,有符号整数 |
|
biClrUsed |
4 |
说明位图使用的调色板中的颜色索引数,为0说明使用所有 |
|
biClrImportant |
4 |
说明对图像显示有重要影响的颜色索引数,为0说明都重要 |
调色板(84 bytes)
不太懂
位图数据(1920*1080 bytes)
这里的biHeight为正数,说明图像倒立,从左下角开始到右上角,以行为主序排列。
如果是24位色图,按照BGR的顺序排列,32位色图按照BGRAlpha排列
从数据上看,第一个像素,也就是左下角像素值为R=c8,G=cc, B=d8
用gimp软件查看左下角像素,发现确实如此
Verilog读取
在以下代码中,我希望输出的RGB数据从图片第0行开始,并且按RGB顺序输出
`timescale 1ns / 1ns
module bmp_tb;
localparam height = 1080;
localparam width = 1920;
localparam bfoffset = 138;
localparam total_size = height * width * 3 + bfoffset;
integer iBmpFileId,iOutFileId,iIndex=0,iCode;
reg [7:0] rBmpData [total_size];
//reg rClk;
reg [7:0] rData;
integer iBmpWidth,iBmpHight,iDataStartIndex,iBmpSize;
initial begin
iBmpFileId = $fopen("D:/verilog/read_bmp/ChurchillBears_1920x1080.bmp","rb");
iOutFileId = $fopen("D:/verilog/read_bmp/ChurchillBears_1920x1080.txt","w+");
iCode = $fread(rBmpData,iBmpFileId);
iBmpWidth = {rBmpData[21],rBmpData[20],rBmpData[19],rBmpData[18]};
iBmpHight = {rBmpData[25],rBmpData[24],rBmpData[23],rBmpData[22]};
iDataStartIndex = {rBmpData[13],rBmpData[12],rBmpData[11],rBmpData[10]};
iBmpSize = {rBmpData[5],rBmpData[4],rBmpData[3],rBmpData[2]};
$display("The image width is %d, height is %d, RGB data starts from %d", iBmpWidth, iBmpHight, iDataStartIndex);
$fclose(iBmpFileId);
for (int i = iBmpHight-1; i>=0; i=i-1) begin
//for (int i = 0; i<iBmpHight; i=i+1) begin
for (int j = 0; j< iBmpWidth; j=j+1) begin
iIndex = i * iBmpWidth * 3 + j*3 + iDataStartIndex;
$fwrite(iOutFileId,"%x",rBmpData[iIndex+2]);
$fwrite(iOutFileId,"%x",rBmpData[iIndex+1]);
$fwrite(iOutFileId,"%x\n",rBmpData[iIndex+0]);
end
end
$fclose(iOutFileId);
#1000 $finish;
end
endmodule
输出结果
确认第一个像素正确