This commit is contained in:
parent
c0e5f1dc84
commit
eb95c5674d
40
bmp.c
40
bmp.c
|
@ -28,12 +28,20 @@ struct BmpInfoHeader {
|
|||
#pragma pack()
|
||||
|
||||
|
||||
void bmpWrite(const char* name, const uch* raw_img, uint32_t width, uint32_t height, uint16_t bits)
|
||||
void bmpWrite(const char* name, const uch* raw_img, uint32_t width, uint32_t height, uint16_t bits, const char* old_name, double radio)
|
||||
{
|
||||
if(!(name && raw_img)) {
|
||||
perror("Error bmpWrite.");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long oldWidth, oldHeight, oldSize, newWidth, newHeight, newSize;
|
||||
oldWidth = width;
|
||||
oldHeight = height;
|
||||
|
||||
newWidth = ((int)(oldWidth * radio) + 3) / 4 * 4;//图像显示不出来原因在于图像长或宽不是4的倍数 保证得到的宽高是4的倍数
|
||||
newHeight = ((int)(oldHeight * radio) + 3) / 4 * 4;
|
||||
|
||||
// 檔案資訊
|
||||
struct BmpFileHeader file_h = {
|
||||
.bfTybe=0x4d42,
|
||||
|
@ -41,7 +49,7 @@ void bmpWrite(const char* name, const uch* raw_img, uint32_t width, uint32_t hei
|
|||
.bfReserved2=0,
|
||||
.bfOffBits=54,
|
||||
};
|
||||
file_h.bfSize = file_h.bfOffBits + width*height * bits/8;
|
||||
file_h.bfSize = file_h.bfOffBits + newWidth*newHeight * bits/8;
|
||||
if(bits==8) {file_h.bfSize+= 1024, file_h.bfOffBits+= 1024;}
|
||||
// 圖片資訊
|
||||
struct BmpInfoHeader info_h = {
|
||||
|
@ -53,10 +61,10 @@ void bmpWrite(const char* name, const uch* raw_img, uint32_t width, uint32_t hei
|
|||
.biClrUsed=0,
|
||||
.biClrImportant=0,
|
||||
};
|
||||
info_h.biWidth = width;
|
||||
info_h.biHeight = height;
|
||||
info_h.biWidth = newWidth;
|
||||
info_h.biHeight = newHeight;
|
||||
info_h.biBitCount = bits;
|
||||
info_h.biSizeImage = width*height * bits/8;
|
||||
info_h.biSizeImage = newWidth*newHeight * bits/8;
|
||||
if(bits == 8) {info_h.biClrUsed=256;}
|
||||
// 寫入檔頭
|
||||
FILE *pFile = NULL;
|
||||
|
@ -88,18 +96,16 @@ void bmpWrite(const char* name, const uch* raw_img, uint32_t width, uint32_t hei
|
|||
fwrite((char*)&raw_img[idx*3 +1], sizeof(char), sizeof(uch), pFile);
|
||||
fwrite((char*)&raw_img[idx*3 +0], sizeof(char), sizeof(uch), pFile);
|
||||
|
||||
unsigned long oldWidth, oldHeight, oldSize, newWidth, newHeight, newSize;
|
||||
// unsigned long oldWidth, oldHeight, oldSize, newWidth, newHeight, newSize;
|
||||
|
||||
oldWidth = width;
|
||||
oldHeight = height;
|
||||
// oldWidth = width;
|
||||
// oldHeight = height;
|
||||
unsigned char *sourceData = (unsigned char*)malloc(oldSize);//该指针指向源位图文件图像数据的内存空间
|
||||
fseek(src_file, 54, SEEK_SET);//使文件的指针指向文件的第55个字节
|
||||
fread(sourceData, oldSize, 1, src_file);//将src_file中的图像数据存储到sourceData指向的内存空间
|
||||
fseek(old_name, 54, SEEK_SET);//使文件的指针指向文件的第55个字节
|
||||
fread(sourceData, oldSize, 1, old_name);//将src_file中的图像数据存储到sourceData指向的内存空间
|
||||
|
||||
double radio = 1.0;// test 倍數
|
||||
|
||||
newWidth = ((int)(oldWidth * radio) + 3) / 4 * 4;//图像显示不出来原因在于图像长或宽不是4的倍数 下面这一步可以保证得到的宽高是4的倍数
|
||||
newHeight = ((int)(oldHeight * radio) + 3) / 4 * 4;
|
||||
// newWidth = ((int)(oldWidth * radio) + 3) / 4 * 4;//图像显示不出来原因在于图像长或宽不是4的倍数 下面这一步可以保证得到的宽高是4的倍数
|
||||
// newHeight = ((int)(oldHeight * radio) + 3) / 4 * 4;
|
||||
|
||||
//10.使用最邻近插值算法进行图片缩放
|
||||
unsigned int x,y,X,Y;//源位图文件像素点宽高和目标位图文件像素点宽高
|
||||
|
@ -186,9 +192,9 @@ void Imgraw_Read(const Imgraw* _this, const char* name) {
|
|||
const Imgraw* p = _this;
|
||||
bmpRead(name, &p->data, &p->width, &p->height, &p->bits);
|
||||
}
|
||||
void Imgraw_Writ(const Imgraw* _this, const char* name) {
|
||||
void Imgraw_Writ(const Imgraw* _this, const char* name, const char* old_name) {
|
||||
const Imgraw* p = _this;
|
||||
bmpWrite(name, p->data, p->width, p->height, p->bits);
|
||||
bmpWrite(name, p->data, p->width, p->height, p->bits, old_name, 1.0);
|
||||
}
|
||||
/*==============================================================*/
|
||||
int main(int argc, char const *argv[]) {
|
||||
|
@ -197,7 +203,7 @@ int main(int argc, char const *argv[]) {
|
|||
// 讀圖
|
||||
Imgraw_Read(&img, "./input/bw2x1.bmp");
|
||||
// 寫圖
|
||||
Imgraw_Writ(&img, "./output/bw2x1(output).bmp");
|
||||
Imgraw_Writ(&img, "./output/bw2x1(output).bmp", "./input/bw2x1.bmp");
|
||||
return 0;
|
||||
}
|
||||
/*==============================================================*/
|
|
@ -0,0 +1,180 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
typedef unsigned char uch;
|
||||
|
||||
// ™n°¸½Y˜‹
|
||||
#pragma pack(2)
|
||||
struct BmpFileHeader {
|
||||
uint16_t bfTybe;
|
||||
uint32_t bfSize;
|
||||
uint16_t bfReserved1;
|
||||
uint16_t bfReserved2;
|
||||
uint32_t bfOffBits;
|
||||
};
|
||||
struct BmpInfoHeader {
|
||||
uint32_t biSize;
|
||||
uint32_t biWidth;
|
||||
uint32_t biHeight;
|
||||
uint16_t biPlanes; // 1=defeaul, 0=custom
|
||||
uint16_t biBitCount;
|
||||
uint32_t biCompression;
|
||||
uint32_t biSizeImage;
|
||||
uint32_t biXPelsPerMeter; // 72dpi=2835, 96dpi=3780
|
||||
uint32_t biYPelsPerMeter; // 120dpi=4724, 300dpi=11811
|
||||
uint32_t biClrUsed;
|
||||
uint32_t biClrImportant;
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
|
||||
void bmpWrite(const char* name, const uch* raw_img,
|
||||
uint32_t width, uint32_t height, uint16_t bits)
|
||||
{
|
||||
if(!(name && raw_img)) {
|
||||
perror("Error bmpWrite.");
|
||||
return;
|
||||
}
|
||||
// ™n°¸ÙYÓ<59>
|
||||
struct BmpFileHeader file_h = {
|
||||
.bfTybe=0x4d42,
|
||||
.bfReserved1=0,
|
||||
.bfReserved2=0,
|
||||
.bfOffBits=54,
|
||||
};
|
||||
file_h.bfSize = file_h.bfOffBits + width*height * bits/8;
|
||||
if(bits==8) {file_h.bfSize+= 1024, file_h.bfOffBits+= 1024;}
|
||||
// ˆDƬÙYÓ<59>
|
||||
struct BmpInfoHeader info_h = {
|
||||
.biSize=40,
|
||||
.biPlanes=1,
|
||||
.biCompression=0,
|
||||
.biXPelsPerMeter=0,
|
||||
.biYPelsPerMeter=0,
|
||||
.biClrUsed=0,
|
||||
.biClrImportant=0,
|
||||
};
|
||||
info_h.biWidth = width;
|
||||
info_h.biHeight = height;
|
||||
info_h.biBitCount = bits;
|
||||
info_h.biSizeImage = width*height * bits/8;
|
||||
if(bits == 8) {info_h.biClrUsed=256;}
|
||||
// Œ‘Èë™nî^
|
||||
FILE *pFile = NULL;
|
||||
// pFile = fopen(name,"wb+");
|
||||
fopen_s(&pFile, name,"wb+");
|
||||
if(!pFile) {
|
||||
perror("Error opening file.");
|
||||
return;
|
||||
}
|
||||
fwrite((char*)&file_h, sizeof(char), sizeof(file_h), pFile);
|
||||
fwrite((char*)&info_h, sizeof(char), sizeof(info_h), pFile);
|
||||
// Œ‘Õ{É«±P
|
||||
if(bits == 8) {
|
||||
for(unsigned i = 0; i < 256; ++i) {
|
||||
uch c = i;
|
||||
fwrite((char*)&c, sizeof(char), sizeof(uch), pFile);
|
||||
fwrite((char*)&c, sizeof(char), sizeof(uch), pFile);
|
||||
fwrite((char*)&c, sizeof(char), sizeof(uch), pFile);
|
||||
fwrite("", sizeof(char), sizeof(uch), pFile);
|
||||
}
|
||||
}
|
||||
// Œ‘ÈëˆDƬÙYÓ<59>
|
||||
size_t alig = ((width*bits/8)*3) % 4;
|
||||
for(int j = height-1; j >= 0; --j) {
|
||||
for(unsigned i = 0; i < width; ++i) {
|
||||
uint32_t idx = j*width +i;
|
||||
if(bits == 24) { // RGBˆDƬ
|
||||
fwrite((char*)&raw_img[idx*3 +2],
|
||||
sizeof(char), sizeof(uch), pFile);
|
||||
fwrite((char*)&raw_img[idx*3 +1],
|
||||
sizeof(char), sizeof(uch), pFile);
|
||||
fwrite((char*)&raw_img[idx*3 +0],
|
||||
sizeof(char), sizeof(uch), pFile);
|
||||
} else if(bits == 8) { // »ÒëAˆD
|
||||
fwrite((char*)&raw_img[idx],
|
||||
sizeof(char), sizeof(uch), pFile);
|
||||
}
|
||||
}
|
||||
// Œ¦ýR4byte
|
||||
for(size_t i = 0; i < alig; ++i) {
|
||||
fwrite("", sizeof(char), sizeof(uch), pFile);
|
||||
}
|
||||
}
|
||||
fclose(pFile);
|
||||
}
|
||||
void bmpRead(const char* name, uch** raw_img,
|
||||
uint32_t* width, uint32_t* height, uint16_t* bits)
|
||||
{
|
||||
if(!(name && raw_img && width && height && bits)) {
|
||||
perror("Error bmpRead.");
|
||||
return;
|
||||
}
|
||||
// ™n°¸ÙYÓ<59>
|
||||
struct BmpFileHeader file_h;
|
||||
// ˆDƬÙYÓ<59>
|
||||
struct BmpInfoHeader info_h;
|
||||
// ×xÈ¡™nî^
|
||||
FILE *pFile = NULL;
|
||||
// pFile = fopen(name, "rb+");
|
||||
fopen_s(&pFile, name, "rb+");
|
||||
if(!pFile) {
|
||||
perror("Error opening file.");
|
||||
return;
|
||||
}
|
||||
fread((char*)&file_h, sizeof(char), sizeof(file_h), pFile);
|
||||
fread((char*)&info_h, sizeof(char), sizeof(info_h), pFile);
|
||||
// ×xÈ¡éLŒ’
|
||||
*width = info_h.biWidth;
|
||||
*height = info_h.biHeight;
|
||||
*bits = info_h.biBitCount;
|
||||
size_t ImgSize = ((size_t)*width) * ((size_t)*height) * 3;
|
||||
*raw_img = (uch*)calloc(ImgSize, sizeof(uch));
|
||||
// ×xÈ¡×xƬÙYÓ<59>ÞDRAW™nÙYÓ<59>
|
||||
fseek(pFile, file_h.bfOffBits, SEEK_SET);
|
||||
size_t alig = ((info_h.biWidth*info_h.biBitCount/8)*3) % 4;
|
||||
for(int j = *height-1; j >= 0; --j) {
|
||||
for(unsigned i = 0; i < *width; ++i) {
|
||||
uint32_t idx = j*(*width)+i;
|
||||
if(*bits == 24) { // RGBˆDƬ
|
||||
fread((char*)&(*raw_img)[idx*3 +2],
|
||||
sizeof(char), sizeof(uch), pFile);
|
||||
fread((char*)&(*raw_img)[idx*3 +1],
|
||||
sizeof(char), sizeof(uch), pFile);
|
||||
fread((char*)&(*raw_img)[idx*3 +0],
|
||||
sizeof(char), sizeof(uch), pFile);
|
||||
} else if(*bits == 8) { // »ÒëAˆD
|
||||
fread((char*)&(*raw_img)[idx],
|
||||
sizeof(char), sizeof(uch), pFile);
|
||||
}
|
||||
}
|
||||
fseek(pFile , (long)alig , SEEK_CUR);
|
||||
}
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
// ˆDÏñ½Y˜‹
|
||||
typedef struct Imgraw {
|
||||
uint32_t width, height;
|
||||
uint16_t bits;
|
||||
uch* data;
|
||||
} Imgraw;
|
||||
void Imgraw_Read(const Imgraw* _this, const char* name) {
|
||||
const Imgraw* p = _this;
|
||||
bmpRead(name, &p->data, &p->width, &p->height, &p->bits);
|
||||
}
|
||||
void Imgraw_Writ(const Imgraw* _this, const char* name) {
|
||||
const Imgraw* p = _this;
|
||||
bmpWrite(name, p->data, p->width, p->height, p->bits);
|
||||
}
|
||||
/*==============================================================*/
|
||||
int main(int argc, char const *argv[]) {
|
||||
// ½¨˜‹
|
||||
Imgraw img = {0, 0, 0, NULL};
|
||||
// ×xˆD
|
||||
Imgraw_Read(&img, "./input/bw2x1.bmp");
|
||||
// Œ‘ˆD
|
||||
Imgraw_Writ(&img, "./output/bw2x1(output).bmp");
|
||||
return 0;
|
||||
}
|
||||
/*==============================================================*/
|
Binary file not shown.
Loading…
Reference in New Issue