在 Linux 上使用 C 保存 BMP 文件



我试图打开bmp文件并使用c代码保存它。我的代码在窗口编译器(Visual Studio(上运行良好,但在使用gcc的Linux上不起作用。即使最终输出的格式是 bmp,它也显示为空文件(白色(。我是使用 linux 和 c 编程的初学者,所以我不确定发生这种情况有什么问题! 我使用 gcc 编译它:gcc bmp.c -o bmp。 下面的代码是我使用的代码。

#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#define  WIDTHBYTES(bits)    (((bits)+31)/32*4)
#pragma pack(push, 1) 
typedef unsigned short WORD;
typedef unsigned long  DWORD;
typedef long           LONG;


typedef struct tagBITMAPFILEHEADER {    
WORD    bfType;  
DWORD   bfSize;  
WORD    bfReserved1;  
WORD    bfReserved2;  
DWORD   bfOffBits;  
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {  
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 tagRGBQUAD { 
unsigned char  rgbBlue;  
unsigned char  rgbGreen; 
unsigned char  rgbRed;   
unsigned char  rgbReserved;
} RGBQUAD;
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;
int main(int argc, char* argv[]){
FILE             *infile;
FILE             *outfile;
BITMAPFILEHEADER  hf;
BITMAPINFOHEADER  hInfo;
RGBQUAD           hRGBpal[256];

unsigned char              *lpImg;

int               i, j, pos, rwsize;
int               nBitCount = 1;
infile = fopen("image.bmp", "rb");
if (infile == NULL)
{
printf("no image");
return 1;
}
fread(&hf, sizeof(BITMAPFILEHEADER), 1, infile);
if (hf.bfType != 0x4d42)
{
printf("ERRORn");
fclose(infile);
exit(1);
}
fread(&hInfo, sizeof(BITMAPINFOHEADER), 1, infile);
if (hInfo.biBitCount == 8 || hInfo.biBitCount == 16 ||
hInfo.biBitCount == 24 || hInfo.biBitCount == 32)
{
nBitCount = hInfo.biBitCount / 8;
if (hInfo.biBitCount == 8)
{
pos = hf.bfOffBits - hf.bfSize - hInfo.biSize;
if (pos > 0)
{
fread((unsigned char *)hRGBpal, sizeof(unsigned char), pos, infile);
}
}
lpImg = (unsigned char*)malloc(hInfo.biSizeImage);
fseek(infile, hf.bfOffBits, SEEK_SET);
fread(lpImg, sizeof(unsigned char), hInfo.biSizeImage, infile);
fclose(infile);
}
rwsize = WIDTHBYTES(hInfo.biBitCount*hInfo.biWidth);
for (i = 0; i < hInfo.biHeight; i++)
{
for (j = 0; j < hInfo.biWidth; j++)
{
lpImg[i*rwsize + j];
}
}
outfile = fopen("out.bmp", "wb")
if (hInfo.biBitCount == 8)
{
hf.bfOffBits = sizeof(BITMAPFILEHEADER)
+ sizeof(BITMAPINFOHEADER) + sizeof(hRGBpal);
}
fwrite(&hf, sizeof(char), sizeof(BITMAPFILEHEADER), outfile);
fwrite(&hInfo, sizeof(char), sizeof(BITMAPINFOHEADER), outfile);
if (hInfo.biBitCount == 8)
{
fwrite(hRGBpal, sizeof(RGBQUAD), 256, outfile);
}
fwrite(lpImg, sizeof(unsigned char), hInfo.biSizeImage, outfile);
fclose(outfile);
if (lpImg)
free(lpImg);
printf("DONE!");}

这可能在这里出错:

typedef unsigned short WORD;
typedef unsigned long  DWORD;
typedef long           LONG;

如果你使用的是 64 位 Linux,long有 64 位。在64位Windows上,它只有32位。对于可移植代码,请使用固定大小的整数:

typedef uint16_t WORD;
typedef uint32_t DWORD;
typedef int32_t LONG;

进一步说明,根本不需要介绍这些丑陋的(我在这里的意见(winapi typedefs。我正在使用的位图文件头的(草率(版本(仍然依赖于"打包结构"功能并将两个结构合并为一个(如下所示:

#pragma pack(push)
#pragma pack(1)
struct bmphdr
{
uint16_t    bfType;
uint32_t    bfSize;
uint32_t    bfReserved;
uint32_t    bfOffBits;
uint32_t    biSize;
uint32_t    biWidth;
int32_t     biHeight;
uint16_t    biPlanes;
uint16_t    biBitCount;
uint32_t    biCompression;
uint32_t    biSizeImage;
int32_t     biXPelsPerMeter;
int32_t     biYPelsPerMeter;
uint32_t    biClrUsed;
uint32_t    biClrImportant;
};
#pragma pack(pop)

最新更新