2017-08-17 20 views
0

bmpファイルを開いてCコードで保存しようとしました。私のコードはウィンドウコンパイラ(Visual Studio)でうまくいきましたが、gccを使ってLinux上で動作しませんでした。最終的な出力形式はbmpですが、空のファイル(白)のように表示されます。私はLinuxとCのプログラミングを使用するための初心者ですので、何が起こっているのか分からない! gcc:gcc bmp.c -o bmpを使ってコンパイルしました。 以下のコードは私が使用したものです。bmpファイルをlinuxでcを使って保存する

#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("ERROR\n"); 
    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!");} 
+0

定義されている? [mcve]を投稿してください。 –

+0

@FelixPalmen申し訳ありません私は怒っているコード全体を追加しました:) – ksh999

+0

あなたのループ 'lpImg [i * rwsize + j];は何もしません。 –

答えて

2

これはおそらく間違ってここに行く:あなたは64ビットのLinuxを使っている場合は

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

longは64ビットです。 64ビットWindowsでは、32ビットしかありません。移植可能なコードの場合、固定サイズの整数を使用します。さらにノートで

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

を、すべてのこれらの醜い(ここでは私の意見)WINAPIの型定義を導入する必要はありません。私は(まだ「パック構造体」機能に依存し、一つに両方の構造体をマージする)使用しているビットマップファイルのヘッダの(ずさん)バージョンは、次のようになります。 `BITMAPFILEHEADER`ように、すべてのこれらの事です

#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) 
+0

それは良いキャッチだ! –

+0

@ ksh999。固定サイズのタイプには「」を含めます。 –

+0

@ ksh999読み取り[64ビットのデータモデル(https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models)組み込み 'long'を使用する場合、結果は、WindowsおよびLinux上の異なる理由は。 (Windows64では 'LLP64'、Linux64では' LP64'が使用されます) –

関連する問題