BMP格式知识之六:对于水平像素被4整除的解释
2015-06-12 23:22
369 查看
4的倍数是像素数据的长度(按字节计)要是4的倍数,
单色位图每像素1/8字节
16色位图每像素1/2字节
256色位图每像素1字节
真彩色位图每像素3字节
每一行图象的数据的长度(按字节计)要是4的倍数,即
单色位图每一行32像素的倍数,不足的补0
16色位图每一行8像素的倍数,不足的补0
256色位图每一行4像素的倍数,不足的补0
真彩色位图麻烦些,只要补够4个字节的倍数就行
struct tagBITMAPFILEHEADER
{unsigned int bfType; // 指明文件类型, 值为 BM
unsigned long bfSize; // 文件大小
unsigned int Reserved1; // 保留字, 值为 0
unsigned int Reserved2; // 保留字, 值为 0
unsigned long bfOffset; // 位图阵列的偏移量, 以字节为单位
} bitmapfileheader;
struct tagBITMAPINFOHEADER
{unsigned long biSize; // 该结构的字节数, 值为 40
unsigned long biWidth;
// 位图的宽度, 以像素为单位
unsigned long biHeight;
// 位图的高度, 以像素为单位
unsigned int biPlanes;
// 目标设备的位面数, 值为 1
unsigned int biBitCount;
// 每个像素所占位数, 为 2色: 1,
// 16色: 4, 256色: 8, 16M色: 24
unsigned long biCompression; // BMP 的压缩方式, 分别为 BI-RGB,
// BI-REL8 或 BI-REL4, 对应值分别
// 为 0, 1, 2
unsigned long biSizeImage; // 位图大小, 以字节为单位
unsigned long biXpelsPerMeter; // 水平分辨率, 单位为像素 / 米
unsigned long biYpelsPerMeter; // 垂直分辨率, 单位为像素 / 米
unsigned long biClrUsed; // 实际使用的颜色数
unsigned long biClrImportant;
// 重要颜色索引值
} bitmapinfoheader;
struct tagRGBQUAD
{unsigned char rgbBlue;
// 蓝色亮度值
unsigned char rgbGreen;
// 绿色亮度值
unsigned char rgbRed; // 红色亮度值
unsigned char rgbReserved;
// 保留字, 为 0
} rgbquad;
-----------------------------------------------------------------
单色位图每像素1/8字节
16色位图每像素1/2字节
256色位图每像素1字节
真彩色位图每像素3字节
每一行图象的数据的长度(按字节计)要是4的倍数,即
单色位图每一行32像素的倍数,不足的补0
16色位图每一行8像素的倍数,不足的补0
256色位图每一行4像素的倍数,不足的补0
真彩色位图麻烦些,只要补够4个字节的倍数就行
struct tagBITMAPFILEHEADER
{unsigned int bfType; // 指明文件类型, 值为 BM
unsigned long bfSize; // 文件大小
unsigned int Reserved1; // 保留字, 值为 0
unsigned int Reserved2; // 保留字, 值为 0
unsigned long bfOffset; // 位图阵列的偏移量, 以字节为单位
} bitmapfileheader;
struct tagBITMAPINFOHEADER
{unsigned long biSize; // 该结构的字节数, 值为 40
unsigned long biWidth;
// 位图的宽度, 以像素为单位
unsigned long biHeight;
// 位图的高度, 以像素为单位
unsigned int biPlanes;
// 目标设备的位面数, 值为 1
unsigned int biBitCount;
// 每个像素所占位数, 为 2色: 1,
// 16色: 4, 256色: 8, 16M色: 24
unsigned long biCompression; // BMP 的压缩方式, 分别为 BI-RGB,
// BI-REL8 或 BI-REL4, 对应值分别
// 为 0, 1, 2
unsigned long biSizeImage; // 位图大小, 以字节为单位
unsigned long biXpelsPerMeter; // 水平分辨率, 单位为像素 / 米
unsigned long biYpelsPerMeter; // 垂直分辨率, 单位为像素 / 米
unsigned long biClrUsed; // 实际使用的颜色数
unsigned long biClrImportant;
// 重要颜色索引值
} bitmapinfoheader;
struct tagRGBQUAD
{unsigned char rgbBlue;
// 蓝色亮度值
unsigned char rgbGreen;
// 绿色亮度值
unsigned char rgbRed; // 红色亮度值
unsigned char rgbReserved;
// 保留字, 为 0
} rgbquad;
-----------------------------------------------------------------
void display_color2(int col, int row) { unsigned int Height, Width; unsigned char info; unsigned char color[2] = {0, 15}; int i, j, t, gap; int k = 0x80; int patch = 0; fseek(fp, 0x36, SEEK_SET); // 0X36 = 54 Height = bitmapinfoheader.biHeight; Width = bitmapinfoheader.biWidth; if (Width / 8 * 8 != Width) { patch = 1; gap = Width - Width / 8 * 8; } fseek(fp, bitmapfileheader.bfOffset, SEEK_SET); for (i = 0; i < Height; i ++) for (j = 0; j < Width / 8 + patch; j ++) { info = fgetc(fp); // write bitmap for (t = 0; t < 8; t ++) {putpoint(col + 8 * j + t, Height - (row + i), color[(info & (k >> t)) >> (7 - t)]); if (patch == 1 && j == Width / 8 && t == gap - 1) break; } } } void display_color16(int col, int row) { unsigned char pal[256][3]; unsigned int Height, Width; char info; unsigned int w, h, byte, gap, num, flag, n; unsigned long biBitCount; fseek(fp, 0x36, SEEK_SET); // 0x36 = 54 for (int i = 0; i < 64; i ++) {fread(&rgbquad, sizeof(rgbquad), 1, fp); pal[i][0] = rgbquad.rgbRed >> 2; pal[i][1] = rgbquad.rgbGreen >> 2; pal[i][2] = rgbquad.rgbBlue >> 2; } set_palette(pal); fseek(fp, bitmapfileheader.bfOffset, SEEK_SET); Width = bitmapinfoheader.biWidth; Height = bitmapinfoheader.biHeight; biBitCount = bitmapinfoheader.biBitCount; n = Width * biBitCount; if ((n / 32 * 32) == n) { gap = 0; flag = 0; } else { num = n / 8; byte = num + 4 - (num - num / 4 * 4); if ((n / 8 * 8) == n) flag = 0; else flag = 1; gap = byte - num - flag; } for (h = 0; h < Height; h ++) { for (w = 0; w < Width / 2; w ++) { info = fgetc(fp); // write bitmap putpoint(col + w * 2, Height - (row + h), (info & 0xf0) >> 4); putpoint(col + w * 2 + 1, Height - (row + h), info & 0x0f); } if (flag == 1) {info = fgetc(fp); putpoint(col + Width - 1, Height - (row + h), (info & 0xf0) >> 4); } fseek(fp, gap, SEEK_CUR); } } void display_color256(int col, int row) { unsigned int Height, Width; unsigned char color; unsigned char pal[256][3]; int i, j, gap, byte; fseek(fp, 0x36, SEEK_SET); // 0x36 = 54 for (i = 0; i < 256; i ++) { fread(&rgbquad, sizeof(rgbquad), 1, fp); pal[i][0] = rgbquad.rgbRed >> 2; pal[i][1] = rgbquad.rgbGreen >> 2; pal[i][2] = rgbquad.rgbBlue >> 2; } set_palette(pal); Width = bitmapinfoheader.biWidth; Height = bitmapinfoheader.biHeight; fseek(fp, bitmapfileheader.bfOffset, SEEK_SET); if ((Width / 4) * 4 == Width) { byte = Width; gap = 0; } else {byte = Width / 4 * 4 + 4; gap = byte - Width; } for (i = 0; i < Height; i ++) { for (j = 0; j < byte - gap; j ++) {color = fgetc(fp); putpoint(col + j, Height - row - i, color); } fseek(fp, gap, SEEK_CUR); } } void display_color16M(int col, int row) { unsigned int Height, Width; int i, j, gap, byte; unsigned char r, g, b; fseek(fp, 0x36, SEEK_SET); // 0X36 = 54 Height = bitmapinfoheader.biHeight; Width = bitmapinfoheader.biWidth; fseek(fp, bitmapfileheader.bfOffset, SEEK_SET); if (((Width * 3) / 4) * 4 / 3 == Width) { byte = Width; gap = 0; } else {byte = (Width * 3) / 4 * 4 + 4; gap = byte - (Width * 3); } for (i = 0; i < Height; i ++) { for (j = 0; j < Width; j ++) { b = fgetc(fp); g = fgetc(fp); r = fgetc(fp); putpoint(col + j, Height - row - i, r, g, b); } fseek(fp, gap, SEEK_CUR); } } //基本的程序片段, 调色板的数据只有16色,256色使用,其他单色,真彩色都省略简化了 void main() { fseek(fp, 0, SEEK_SET); fread(&bitmapfileheader, sizeof(bitmapfileheader), 1, fp); fread(&bitmapinfoheader, sizeof(bitmapinfoheader), 1, fp); switch (bitmapinfoheader.biBitCount) { case 1 : display_color2(0, 0); break; case 4 : display_color16(0, 0); break; case 8 : display_color256(0, 0); break; case 24: display_color16M(0, 0); break; } }
相关文章推荐
- 《场景调研》
- 为何毕业即失业
- 单元测试系列之3:测试整合之王Unitils
- [6] MQTT,mosquitto,Eclipse Paho---MQTT消息格式之CONNECT消息格式分析
- hdu 3999 The order of a Tree
- MFC六大关键技术之——消息映射与命令传递
- 查表大小
- 设计模式1--简单工厂
- 剖析CPU温度监控技术
- extern字符串常量,宏定义字符串常量,怎么选
- 中科院NLPIR中文分词java版
- BMP格式知识之五:BMP文件格式(全一/二)
- Linux网络编程之socket相关结构体
- SuperBlock损坏修复
- Uva - 1594 - Ducci Sequence
- Uva - 1594 - Ducci Sequence
- BMP格式知识之四:BMP文件详解
- linux内存源码分析 - SLAB分配器概述
- Divisibility by Eight (数学)
- log4Cpp学习(本文转载)