#include <cv.h>
#include <highgui.h>
#include <iostream>
//#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <fstream>
#include<opencv2/opencv.hpp>
//必须得加上,才可以使用imread、MAT等opencv功能
using namespace cv;
using namespace std;
#pragma pack(2)//必须得写,否则sizeof得不到正确的结果
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef long LONG;
typedef struct {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
typedef struct {
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagPALETTEENTRY { // pe
BYTE peRed;
BYTE peGreen;
BYTE peBlue;
BYTE peFlags;
} PALETTEENTRY;
//void saveBitmap()
int main()
{
//FILE *fptest = fopen("F:/Desktop/写bmp/test.bmp", "wb+");
//if (fptest == NULL)
//{
// printf("file open failed.");
// exit(1);
//}
//BYTE *test = (BYTE *)malloc(8);
//test[0] = 255;
//test[1] = 128;
//test[2] = 0;
//test[3] = 255;
//test[4] = 255;
//test[5] = 255;
//test[6] = 255;
//test[7] = 255;
//fwrite(test, 8, 1, fptest);
//fclose(fptest);
//原来图片的大小
Mat KH = imread("F:/Desktop/写bmp/1KH.tif", 0);
Mat KL = imread("F:/Desktop/写bmp/1KL.tif", 0);
Mat CH = imread("F:/Desktop/写bmp/2CH.tif", 0);
Mat CL = imread("F:/Desktop/写bmp/2CL.tif", 0);
Mat MH = imread("F:/Desktop/写bmp/3MH.tif", 0);
Mat ML = imread("F:/Desktop/写bmp/3ML.tif", 0);
Mat YH = imread("F:/Desktop/写bmp/4YH.tif", 0);
Mat YL = imread("F:/Desktop/写bmp/4YL.tif", 0);
int origin_row = MH.rows;//原图高(有多少行点)
int origin_col = MH.cols;//原图宽(有多少列点)
int col;
// Write to file
FILE *fp = fopen("F:/Desktop/写bmp/0707_test2.bmp", "wb+");
if (fp == NULL)
{
printf("file open failed.");
exit(1);
}
// Define BMP Size
const int height = origin_row;//高度:单位是像素
const int width = origin_col; //宽度:单位是像素,biWidth必须是4的倍数
const int BitPerPixel = 8;//用n位来表示每个像素点,n=1时8个像素占一个字节,n=4时两个像素一个字节,n=8时一个像素一个字节
/*Windows规定一个扫描行所占的字节数必须是4的倍数,不足的用0去填补*/
//一个扫描行所占的字节数:
int DataSizePerLine = (width * BitPerPixel + 31) / 8;
DataSizePerLine = DataSizePerLine / 4 * 4;
const int size = DataSizePerLine * height;//图像的大小:单位是位
//const int size = height * width * BitPerPixel;//图像的大小
//参数设置:https://blog.csdn.net/lanbing510/article/details/8176231
//程序主体:https://blog.csdn.net/kupepoem/article/details/43307387
//调色板:https://blog.csdn.net/szlcw1/article/details/16891359
//8位位深程序体参考:https://blog.csdn.net/jonahzheng/article/details/8029870
/****************** Part.1 Create Bitmap File Header(bmp文件头)******************/
BITMAPFILEHEADER fileHeader;
fileHeader.bfType = 0x4D42;//说明文件的类型,该值必需是0x4D42,也就是字符'BM',否则表示根本不是BMP
fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(PALETTEENTRY) * 256 + size;
//fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + size;
//说明该位图文件的总的大小,单位为字节
fileHeader.bfReserved1 = 0;//保留,必须设置为0
fileHeader.bfReserved2 = 0;//保留,必须设置为0
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(PALETTEENTRY) * 256;
//fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
//说明从文件头开始到实际的图象数据之间的字节的偏移量。
//这个参数是非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,所以你可以用这个偏移值迅速的从文件中读取到位数据。
fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
/******************* Part.2 Create Bitmap Info Header(位图信息段)******************/
BITMAPINFOHEADER bitmapHeader = { 0 };
bitmapHeader.biSize = sizeof(BITMAPINFOHEADER);//说明BITMAPINFOHEADER结构所需要的字节数
bitmapHeader.biWidth = width;//说明图象的宽度,以像素为单位。
bitmapHeader.biHeight = -height;//说明图象的高度,以象素为单位。
//如果height值是一个正数,说明图像是倒向的,即:数据的第一行其实是图像的最后一行,如果该值是一个负数,则说明图像是正向的。
bitmapHeader.biPlanes = 1;//表示bmp图片的平面属,显然显示器只有一个平面,所以恒等于1
bitmapHeader.biBitCount = BitPerPixel;//比特数/像素,每个像素点用几位来表示,其值为1、4、8、16、24、或32。
bitmapHeader.biCompression = 0; //BI_RGB没有压缩
bitmapHeader.biSizeImage = size;
//图象数据的大小,按照bit/像素*像素=bit,再除以8,得到图像大小的字节数
//以字节为单位。当用BI_RGB格式时,可设置为0。
//bitmapHeader.biXPelsPerMeter = 360 / 25.4 * 1000;//说明水平分辨率,用像素/米表示。
//bitmapHeader.biYPelsPerMeter = 400 / 25.4 * 1000;//说明垂直分辨率,用像素/米表示。
bitmapHeader.biClrUsed = 0; //实际使用的彩色表中的颜色索引数,设为0表示使用所有的调色板项。
bitmapHeader.biClrImportant = 0; //有重要影响的颜色索引数,设为0的时候表示都重要。
fwrite(&bitmapHeader, sizeof(BITMAPINFOHEADER), 1, fp);
int size_bitmapfileheader = sizeof(BITMAPFILEHEADER);
int size_bitmapinfoheader = sizeof(BITMAPINFOHEADER);
int size_palettentry = sizeof(PALETTEENTRY);
/************************ Part.3 Create PALETTEENTRY****************************/
//typedef struct tagPALETTEENTRY { // pe
// BYTE peRed;
// BYTE peGreen;
// BYTE peBlue;
// BYTE peFlags;
//} PALETTEENTRY;
PALETTEENTRY paletteentry[256];
for (int k = 0; k < 256; k++)
{
int red;
int green;
int blue;
if (k <= 0)
{
red = 255;
green = 255;
blue = 255;
}
else if (k <= 3)
{
red = 255;
green = 241;
blue = 0;
}
else if (k <= 12)
{
red = 228;
green = 0;
blue = 127;
}
else if (k <= 15)
{
red = 230;
green = 0;
blue = 18;
}
else if (k <= 48)
{
red = 0;
green = 160;
blue = 233;
}
else if (k <= 51)
{
red = 0;
green = 153;
blue = 68;
}
else if (k <= 60)
{
red = 29;
green = 32;
blue = 136;
}
else if (k <= 63)
{
red = 31;
green = 49;
blue = 52;
}
else if (k <= 192)
{
red = 35;
green = 24;
blue = 21;
}
else if (k <= 195)
{
red = 34;
green = 27;
blue = 0;
}
else if (k <= 204)
{
red = 30;
green = 0;
blue = 1;
}
else if (k <= 207)
{
red = 32;
green = 0;
blue = 1;
}
else if (k <= 240)
{
red = 0;
green = 1;
blue = 34;
}
else if (k <= 243)
{
red = 0;
green = 3;
blue = 0;
}
else if (k <= 252)
{
red = 0;
green = 0;
blue = 5;
}
else if (k <= 255)
{
red = 0;
green = 0;
blue = 0;
}
paletteentry[k].peRed = red;
paletteentry[k].peGreen = green;
paletteentry[k].peBlue = blue;
paletteentry[k].peFlags = 0;
fwrite(&paletteentry[k], 4, 1, fp);
}
/************************ Part.4 Create Data****************************/
//fwrite(%获取数据的变量地址,写入数据项为几个字节大小size,数据项的个数 n,文件)
//int a = KH.rows;
//int b = KH.cols;
//int c = row;
//int d = col;
//成功的:.at<uchar>要小于这个数 KH.rows-1, KH.cols-1
//int bb = KH.at<uchar>(KH.rows-1, KH.cols-1) / 255;
//const int size = height * width * BitPerPixel;//图像的大小:单位是位
BYTE *bits = (BYTE *)malloc(size);
// Clear
//memset(bits, 0xFF, size);
int count = 0;
for (int q = 0;q < height;q++)
{
for (int w = 0;w < DataSizePerLine;w++)
{
//DataSizePerLine
if (w < width) {
int n7 = !(KH.at<uchar>(q, w) / 255);
int n6 = !(KL.at<uchar>(q, w) / 255);
int n5 = !(CH.at<uchar>(q, w) / 255);
int n4 = !(CL.at<uchar>(q, w) / 255);
int n3 = !(MH.at<uchar>(q, w) / 255);
int n2 = !(ML.at<uchar>(q, w) / 255);
int n1 = !(YH.at<uchar>(q, w) / 255);
int n0 = !(YL.at<uchar>(q, w) / 255);
bits[count++] = n7 * pow(2, 7) + n6 * pow(2, 6) + n5 * pow(2, 5) + n4 * pow(2, 4) + n3 * pow(2, 3) + n2 * pow(2, 2) + n1 * pow(2, 1) + n0 * pow(2, 0);
}
else
bits[count++] = 0;
}
}
fwrite(bits, size, 1, fp);
fclose(fp);
return 0;
}
#include <highgui.h>
#include <iostream>
//#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <fstream>
#include<opencv2/opencv.hpp>
//必须得加上,才可以使用imread、MAT等opencv功能
using namespace cv;
using namespace std;
#pragma pack(2)//必须得写,否则sizeof得不到正确的结果
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef long LONG;
typedef struct {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
typedef struct {
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagPALETTEENTRY { // pe
BYTE peRed;
BYTE peGreen;
BYTE peBlue;
BYTE peFlags;
} PALETTEENTRY;
//void saveBitmap()
int main()
{
//FILE *fptest = fopen("F:/Desktop/写bmp/test.bmp", "wb+");
//if (fptest == NULL)
//{
// printf("file open failed.");
// exit(1);
//}
//BYTE *test = (BYTE *)malloc(8);
//test[0] = 255;
//test[1] = 128;
//test[2] = 0;
//test[3] = 255;
//test[4] = 255;
//test[5] = 255;
//test[6] = 255;
//test[7] = 255;
//fwrite(test, 8, 1, fptest);
//fclose(fptest);
//原来图片的大小
Mat KH = imread("F:/Desktop/写bmp/1KH.tif", 0);
Mat KL = imread("F:/Desktop/写bmp/1KL.tif", 0);
Mat CH = imread("F:/Desktop/写bmp/2CH.tif", 0);
Mat CL = imread("F:/Desktop/写bmp/2CL.tif", 0);
Mat MH = imread("F:/Desktop/写bmp/3MH.tif", 0);
Mat ML = imread("F:/Desktop/写bmp/3ML.tif", 0);
Mat YH = imread("F:/Desktop/写bmp/4YH.tif", 0);
Mat YL = imread("F:/Desktop/写bmp/4YL.tif", 0);
int origin_row = MH.rows;//原图高(有多少行点)
int origin_col = MH.cols;//原图宽(有多少列点)
int col;
// Write to file
FILE *fp = fopen("F:/Desktop/写bmp/0707_test2.bmp", "wb+");
if (fp == NULL)
{
printf("file open failed.");
exit(1);
}
// Define BMP Size
const int height = origin_row;//高度:单位是像素
const int width = origin_col; //宽度:单位是像素,biWidth必须是4的倍数
const int BitPerPixel = 8;//用n位来表示每个像素点,n=1时8个像素占一个字节,n=4时两个像素一个字节,n=8时一个像素一个字节
/*Windows规定一个扫描行所占的字节数必须是4的倍数,不足的用0去填补*/
//一个扫描行所占的字节数:
int DataSizePerLine = (width * BitPerPixel + 31) / 8;
DataSizePerLine = DataSizePerLine / 4 * 4;
const int size = DataSizePerLine * height;//图像的大小:单位是位
//const int size = height * width * BitPerPixel;//图像的大小
//参数设置:https://blog.csdn.net/lanbing510/article/details/8176231
//程序主体:https://blog.csdn.net/kupepoem/article/details/43307387
//调色板:https://blog.csdn.net/szlcw1/article/details/16891359
//8位位深程序体参考:https://blog.csdn.net/jonahzheng/article/details/8029870
/****************** Part.1 Create Bitmap File Header(bmp文件头)******************/
BITMAPFILEHEADER fileHeader;
fileHeader.bfType = 0x4D42;//说明文件的类型,该值必需是0x4D42,也就是字符'BM',否则表示根本不是BMP
fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(PALETTEENTRY) * 256 + size;
//fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + size;
//说明该位图文件的总的大小,单位为字节
fileHeader.bfReserved1 = 0;//保留,必须设置为0
fileHeader.bfReserved2 = 0;//保留,必须设置为0
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(PALETTEENTRY) * 256;
//fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
//说明从文件头开始到实际的图象数据之间的字节的偏移量。
//这个参数是非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,所以你可以用这个偏移值迅速的从文件中读取到位数据。
fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
/******************* Part.2 Create Bitmap Info Header(位图信息段)******************/
BITMAPINFOHEADER bitmapHeader = { 0 };
bitmapHeader.biSize = sizeof(BITMAPINFOHEADER);//说明BITMAPINFOHEADER结构所需要的字节数
bitmapHeader.biWidth = width;//说明图象的宽度,以像素为单位。
bitmapHeader.biHeight = -height;//说明图象的高度,以象素为单位。
//如果height值是一个正数,说明图像是倒向的,即:数据的第一行其实是图像的最后一行,如果该值是一个负数,则说明图像是正向的。
bitmapHeader.biPlanes = 1;//表示bmp图片的平面属,显然显示器只有一个平面,所以恒等于1
bitmapHeader.biBitCount = BitPerPixel;//比特数/像素,每个像素点用几位来表示,其值为1、4、8、16、24、或32。
bitmapHeader.biCompression = 0; //BI_RGB没有压缩
bitmapHeader.biSizeImage = size;
//图象数据的大小,按照bit/像素*像素=bit,再除以8,得到图像大小的字节数
//以字节为单位。当用BI_RGB格式时,可设置为0。
//bitmapHeader.biXPelsPerMeter = 360 / 25.4 * 1000;//说明水平分辨率,用像素/米表示。
//bitmapHeader.biYPelsPerMeter = 400 / 25.4 * 1000;//说明垂直分辨率,用像素/米表示。
bitmapHeader.biClrUsed = 0; //实际使用的彩色表中的颜色索引数,设为0表示使用所有的调色板项。
bitmapHeader.biClrImportant = 0; //有重要影响的颜色索引数,设为0的时候表示都重要。
fwrite(&bitmapHeader, sizeof(BITMAPINFOHEADER), 1, fp);
int size_bitmapfileheader = sizeof(BITMAPFILEHEADER);
int size_bitmapinfoheader = sizeof(BITMAPINFOHEADER);
int size_palettentry = sizeof(PALETTEENTRY);
/************************ Part.3 Create PALETTEENTRY****************************/
//typedef struct tagPALETTEENTRY { // pe
// BYTE peRed;
// BYTE peGreen;
// BYTE peBlue;
// BYTE peFlags;
//} PALETTEENTRY;
PALETTEENTRY paletteentry[256];
for (int k = 0; k < 256; k++)
{
int red;
int green;
int blue;
if (k <= 0)
{
red = 255;
green = 255;
blue = 255;
}
else if (k <= 3)
{
red = 255;
green = 241;
blue = 0;
}
else if (k <= 12)
{
red = 228;
green = 0;
blue = 127;
}
else if (k <= 15)
{
red = 230;
green = 0;
blue = 18;
}
else if (k <= 48)
{
red = 0;
green = 160;
blue = 233;
}
else if (k <= 51)
{
red = 0;
green = 153;
blue = 68;
}
else if (k <= 60)
{
red = 29;
green = 32;
blue = 136;
}
else if (k <= 63)
{
red = 31;
green = 49;
blue = 52;
}
else if (k <= 192)
{
red = 35;
green = 24;
blue = 21;
}
else if (k <= 195)
{
red = 34;
green = 27;
blue = 0;
}
else if (k <= 204)
{
red = 30;
green = 0;
blue = 1;
}
else if (k <= 207)
{
red = 32;
green = 0;
blue = 1;
}
else if (k <= 240)
{
red = 0;
green = 1;
blue = 34;
}
else if (k <= 243)
{
red = 0;
green = 3;
blue = 0;
}
else if (k <= 252)
{
red = 0;
green = 0;
blue = 5;
}
else if (k <= 255)
{
red = 0;
green = 0;
blue = 0;
}
paletteentry[k].peRed = red;
paletteentry[k].peGreen = green;
paletteentry[k].peBlue = blue;
paletteentry[k].peFlags = 0;
fwrite(&paletteentry[k], 4, 1, fp);
}
/************************ Part.4 Create Data****************************/
//fwrite(%获取数据的变量地址,写入数据项为几个字节大小size,数据项的个数 n,文件)
//int a = KH.rows;
//int b = KH.cols;
//int c = row;
//int d = col;
//成功的:.at<uchar>要小于这个数 KH.rows-1, KH.cols-1
//int bb = KH.at<uchar>(KH.rows-1, KH.cols-1) / 255;
//const int size = height * width * BitPerPixel;//图像的大小:单位是位
BYTE *bits = (BYTE *)malloc(size);
// Clear
//memset(bits, 0xFF, size);
int count = 0;
for (int q = 0;q < height;q++)
{
for (int w = 0;w < DataSizePerLine;w++)
{
//DataSizePerLine
if (w < width) {
int n7 = !(KH.at<uchar>(q, w) / 255);
int n6 = !(KL.at<uchar>(q, w) / 255);
int n5 = !(CH.at<uchar>(q, w) / 255);
int n4 = !(CL.at<uchar>(q, w) / 255);
int n3 = !(MH.at<uchar>(q, w) / 255);
int n2 = !(ML.at<uchar>(q, w) / 255);
int n1 = !(YH.at<uchar>(q, w) / 255);
int n0 = !(YL.at<uchar>(q, w) / 255);
bits[count++] = n7 * pow(2, 7) + n6 * pow(2, 6) + n5 * pow(2, 5) + n4 * pow(2, 4) + n3 * pow(2, 3) + n2 * pow(2, 2) + n1 * pow(2, 1) + n0 * pow(2, 0);
}
else
bits[count++] = 0;
}
}
fwrite(bits, size, 1, fp);
fclose(fp);
return 0;
}