どこが間違っていますか?

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
fabersid
記事: 42
登録日時: 6年前

どこが間違っていますか?

#1

投稿記事 by fabersid » 6年前

起きる問題:強制終了
もっと効率的な宣言があれば教えていただきたいです。

コード:

#include <stdio.h>
#include <string.h>
typedef struct type_BMP{
	char H00[(2+1)*2]; //bfType         'As Integer 'ファイルタイプ
	char H02[(2+1)*4]; //bfSize         'As Long    'ファイルサイズ[byte]
	char H06[(2+1)*2]; //bfReserved1    'As Integer '予約領域1
	char H08[(2+1)*2]; //bfReserved2    'As Integer '予約領域2
	char H0A[(2+1)*4]; //bfOffBits      'As Long    'ファイル先頭から画像データまでのオフセット[byte]
	char H0E[(2+1)*4]; //biSize         'As Long    '情報ヘッダサイズ[byte]
	char H12[(2+1)*4]; //biWidth        'As Long    '画像の幅[ピクセル]
	char H16[(2+1)*2]; //biHeight       'As Long    '画像の高さ[ピクセル]
	char H1A[(2+1)*2]; //biPlanes       'As Integer 'プレーン数
	char H1C[(2+1)*2]; //biBitCount     'As Integer '色ビット数[bit]
	char H1E[(2+1)*4]; //biCompression  'As Long    '圧縮形式
	char H22[(2+1)*4]; //biSizeImage    'As Long    '画像データサイズ[byte]
	char H26[(2+1)*4]; //biXPixPerMeter 'As Long    '水平解像度[dot/m]
	char H2A[(2+1)*4]; //biYPixPerMeter 'As Long    '垂直解像度[dot/m]
	char H2E[(2+1)*4]; //biClrUsed      'As Long    '格納パレット数[使用色数]
	char H32[(2+1)*4]; //biCirImportant 'As Long    '重要色数
}BMP;

void BMP_set(BMP *);//,int,char);

/* 4バイトデータをリトルエンディアンに変換する */
#define  ULONG_B2L(a)                                              \
         (unsigned long)                                           \
         (                                                         \
             ((unsigned long)(*((unsigned char *)a    )) << 24) |  \
             ((unsigned long)(*((unsigned char *)a + 1)) << 16) |  \
             ((unsigned long)(*((unsigned char *)a + 2)) <<  8) |  \
             ((unsigned long)(*((unsigned char *)a + 3))      )    \
         )
/* 2バイトデータをリトルエンディアンに変換する */
#define  USHORT_B2L(a)                                             \
         (unsigned long)                                           \
         (                                                         \
             ((unsigned long)(*((unsigned char *)a + 2)) <<  8) |  \
             ((unsigned long)(*((unsigned char *)a + 3))      )    \
         )

int main(int argc,char *argv[]){//設定値上書き用
	BMP outFile;
	BMP_set(&outfile);//,argc,*argv[0]);
	//argc==where_exe+row
	printf("%d",ULONG_B2L(16));
}

void BMP_set(BMP *outfile){//,int argc,char argv0){//初期値設定用
	strncpy(outfile->H00,"42 4d",sizeof(outfile->H00));
	//strcpy(file->H0A,"36 00");
}

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: どこが間違っていますか?

#2

投稿記事 by みけCAT » 6年前

fabersid さんが書きました:どこが間違っていますか?
  • 未定義の識別子outfileが使われている (コンパイルエラー、outFileの間違い?)
  • ULONG_B2Lの「返り値」はprintfで出力するには書式%luを使うはずのunsigned long型なのに、
    int型のデータを出力するための書式%dが使われている (int型のサイズとlong型のサイズが違う環境では誤動作の原因)
  • 16という適当な数値をULONG_B2Lの引数として渡し、同マクロ中でそれを無理やりポインタにキャストしてデリファレンスしている (致命的)
というところが間違っていますね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: どこが間違っていますか?

#3

投稿記事 by みけCAT » 6年前

fabersid さんが書きました:もっと効率的な宣言があれば教えていただきたいです。
「宣言」の目的によるかもしれません。
何がしたいのでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: どこが間違っていますか?

#4

投稿記事 by へにっくす » 6年前

コードから察するに

Bitmapファイルフォーマット
http://www.umekkii.jp/data/computer/fil ... bitmap.cgi

を作成したいのでしょうか。
であればいろいろ間違っています。
何ですべてchar[]型に統一してるのでしょうか?
バイナリと文字列の違いは分かっていますか?
ULONG_B2L(16)と何で数値を引数にしているのでしょうか?
ULONG_B2Lの引数の型は数値を想定していないですよ。
written by へにっくす

fabersid
記事: 42
登録日時: 6年前

Re: どこが間違っていますか?

#5

投稿記事 by fabersid » 6年前

例えばexe に ffffffffffffffffff000000 ffffffffffffffffff000000 ffffffffffffffffff000000
   18個のf&6個の0 18個のf&6個の0 18個のf&6個の0
のようにコマンドライン引数として入力すると
白3×3のbmpができるというものを作っています。

VBA(String型がある・バイナリは不得意)や
C(String型がない・バイナリは得意)でも意外と難しい

なのでそれぞれ質問サイトで質問しプログラミングしています。
オフトピック
exeのできるCのほうが優先

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: どこが間違っていますか?

#6

投稿記事 by へにっくす » 6年前

ULONG_B2L、USHORT_B2Lなんて定義しなくてもちゃんとエンディアン変換関数があります。
ネットワーク関数の一つなので、Winsock2.hをインクルードする必要がありますが。

https://corgi-lab.com/programming/c-lang/warn-endian/
written by へにっくす

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: どこが間違っていますか?

#7

投稿記事 by へにっくす » 6年前

fabersid さんが書きました:例えばexe に ffffffffffffffffff000000 ffffffffffffffffff000000 ffffffffffffffffff000000
   18個のf&6個の0 18個のf&6個の0 18個のf&6個の0
のようにコマンドライン引数として入力すると
白3×3のbmpができるというものを作っています。
ということは、argvにわたってくるのは文字列なので、それをバイナリに変換する必要があるってことです。
そこのところ分かっていますか?
written by へにっくす

fabersid
記事: 42
登録日時: 6年前

Re: どこが間違っていますか?

#8

投稿記事 by fabersid » 6年前

fopen をwbで呼び出し
argvをintに変換し
putc で ファイルに出力すればいいと思いますが、

自分だけでは組むことができません。
オフトピック
へにっくす さんが書きました:ネットワーク関数の一つなので
盲点でした。
わざわざ「-ネットワーク」をつけて調べてました。

かずま

Re: どこが間違っていますか?

#9

投稿記事 by かずま » 6年前

3x3 の場合、引数は 3個ですが、
1ピクセルが RGB 3バイトで、1行 3ピクセルなら 9バイト。
ビットマップファイルは、1行が 4 の倍数でなければならないので
3バイトのパディングを入れて 12バイトにし、16進文字列で
24文字ですね。パディングは 16進6文字の 0。

4x4 の場合は、引数は 4個で、1行12バイト。パディングなしの 24文字。
5x5 の場合は、引数は 5個で、1行(15+パディング1)バイトの 32文字。

コード:

#include <stdio.h>    // fopen, fclose, fwrite, puts
#include <string.h>   // strlen
#include <windows.h>  // BITMAPFILEHEADER, BITMAPINFOHEADER

const char *filename = "3x3.bmp";

void set2(void *vp, unsigned short x)
{
    char *p = (char *)vp;
    p[0] = x; p[1] = x >> 8;
}

void set4(void *vp, unsigned int x)
{
    char *p = (char *)vp;
    p[0] = x; p[1] = x >> 8; p[2] = x >> 16; p[3] = x >> 24;
}

unsigned char *set(unsigned char *p, const char *v)
{
    int x;
    for (; *v; v += 2) {
        sscanf(v, "%2x", &x);
        *p++ = x;
    }
    return p;
}

int main(int argc, char *argv[])
{
    if (argc < 4) return puts("no args"), 1;
    int height = argc - 1;
    int width = height;
    int dataSize = strlen(argv[1]) / 2 * height;
    int headerSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    printf("width=%d, dataSize = %d\n", width, dataSize);
    static unsigned char buf[1024] = "BM";
    BITMAPFILEHEADER *bf = (BITMAPFILEHEADER *)buf;
    BITMAPINFOHEADER *bi = (BITMAPINFOHEADER *)(buf + sizeof(BITMAPFILEHEADER));

    set4(&bf->bfSize, headerSize + dataSize);
    set4(&bf->bfOffBits, headerSize);

    set4(&bi->biSize, sizeof(BITMAPINFOHEADER));
    set4(&bi->biWidth, width);
    set4(&bi->biHeight, height);
    set2(&bi->biPlanes, 1);
    set2(&bi->biBitCount, 24);
    set4(&bi->biSizeImage, dataSize);

    unsigned char *p = buf + headerSize;
    for (int i = argc; --i > 0; ) p = set(p, argv[i]);

    FILE *fp = fopen(filename, "wb");
    if (!fp) return puts("fopen failed"), 1;
    fwrite(buf, 1, headerSize + dataSize, fp);
    fclose(fp);
}

fabersid
記事: 42
登録日時: 6年前

現在のコード

#10

投稿記事 by fabersid » 6年前

出力期待値
► スポイラーを表示
実際の出力
► スポイラーを表示
現在のコード
► スポイラーを表示

かずま

Re: どこが間違っていますか?

#11

投稿記事 by かずま » 6年前

コード:

        ret[i*3+1]=arg[i*2+1]; のあとに
        ret[i*3+2] = ' '; がないからでは?

かずま

Re: どこが間違っていますか?

#12

投稿記事 by かずま » 6年前

次のようにすれば、strcpy も space_htonl も要りません。

コード:

BMP BMP_set(int argc, char argv1[])
{
    static BMP outFile = {
        "42 4d",         //2
        "00 00 00 00",   //4
        "00 00",         //2
        "00 00",         //2
        "36 00 00 00",   //4
        "28 00 00 00",   //4
        "00 00 00 00",   //4
        "00 00 00 00",   //4
        "00 00",         //2
        "00 00",         //2
        "00 00 00 00",   //4
        "00 00 00 00",   //4
        "00 00 00 00",   //4
        "00 00 00 00",   //4
        "00 00 00 00",   //4
        "00 00 00 00",   //4
    };
    int row = argc - 1, col = 0;

    if (argc > 1) col = strlen(argv1);
    sprintf(outFile.H12, "%02x %02x %02x %02x",
        col & 0xff, col>>8 & 0xff, col>>16 & 0xff, col>>24 & 0xff);
    sprintf(outFile.H16, "%02x %02x %02x %02x",
        row & 0xff, row>>8 & 0xff, row>>16 & 0xff, row>>24 & 0xff);
    return outFile;
}
でも、col = strlen(argv1); は間違っていると思います。
3x3 のビットマップファイルを作りたいのに、
これでは、24x3 になってしまいますよ。

fabersid
記事: 42
登録日時: 6年前

Re: どこが間違っていますか?

#13

投稿記事 by fabersid » 6年前

現在のコード(BMP_setの更新)
► スポイラーを表示
実行
► スポイラーを表示

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: どこが間違っていますか?

#14

投稿記事 by みけCAT » 6年前

fabersid さんが書きました:あとは矢印のところを計算しargvをくっつけてファイル出力するだけですよね?
BMP 画像の扱いかたを参考にすると

コード:

BMP_maker ffffff00
42 4d
00 00 00 00     <― 画像ファイルの大きさ。固定、または複数の大きさに対応するなら計算する
00 00
00 00
36 00 00 00
28 00 00 00
01 00 00 00 ← 画像の横幅。3x3のビットマップを作りたかったはずなのになんで1?
01 00 00 00 ← 画像の縦幅。3x3のビットマップを作りたかったはずなのになんで1?
00 00           <― 「プレーン数」。1固定で計算の必要は無い
00 00           <― ピクセルあたりのビット数。計算というよりフォーマットに応じて決め打ち?長さから計算する?
00 00 00 00
00 00 00 00     <― 画像データ本体の大きさ。固定、または複数の大きさに対応するなら計算する
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
なので、そうだとは言えないと思います。
オフトピック
参考サイトには「識別バイト。BM(0x45 0x4d)でなければならない。」と書かれていますが、
実際のBMPファイルを確認すると42 4Dだったので、ここは現状でいいと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

fabersid
記事: 42
登録日時: 6年前

引数を書き忘れていました。

#15

投稿記事 by fabersid » 6年前

すみません、引数を乗せ忘れていました。
出力を簡単にテストするために
引数:ffffff00
でテストしてました。

コード:

BMP_maker ffffff00
42 4d
00 00 00 00     <― 画像ファイルの大きさ。固定、または複数の大きさに対応するなら計算する
00 00
00 00
36 00 00 00
28 00 00 00
01 00 00 00 ← 画像の横幅。3x3のビットマップを作りたかったはずなのになんで1?
01 00 00 00 ← 画像の縦幅。3x3のビットマップを作りたかったはずなのになんで1?
00 00           <― 「プレーン数」。1固定で計算の必要は無い
00 00           <― ピクセルあたりのビット数。計算というよりフォーマットに応じて決め打ち?長さから計算する?
00 00 00 00
00 00 00 00     <― 画像データ本体の大きさ。固定、または複数の大きさに対応するなら計算する
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: どこが間違っていますか?

#16

投稿記事 by へにっくす » 6年前

みけCAT さんが書きました:
オフトピック
参考サイトには「識別バイト。BM(0x45 0x4d)でなければならない。」と書かれていますが、
実際のBMPファイルを確認すると42 4Dだったので、ここは現状でいいと思います。
BMのアスキーコードは0x42 0x4Dです。 0x45は'E'を示すので間違いですね。
参考サイトのソースにも

コード:

bmpFileHeader.bfType = 0x4d42;	/* "BM" */
となっていますね。誰も突っ込まれなかったのだろうか…
written by へにっくす

fabersid
記事: 42
登録日時: 6年前

先ほどの追記

#17

投稿記事 by fabersid » 6年前

先ほどの内容
► スポイラーを表示
計算するといっても詰め物である00の数がわからない以上
ファイルとデータ本体の大きさがわかりません。
また、初期値の値を変更したので
「プレーン数」とピクセル当たりのビット数(biBitCount 2byte 色ビット数[bit])
がそれぞれ
01 00(10行目)
18 00(11行目)
になりました。
現在のコード
► スポイラーを表示

かずま

Re: どこが間違っていますか?

#18

投稿記事 by かずま » 6年前

ビットマップファイルというバイナリファイルを作りたいのに、
文字列のデータをプログラム内に作るという意味が理解できません。

No.9 のプログラムは無視されたようですね。

引数でデータを指定すると大きなビットマップファイルが
作りづらいのでファイルから読み込むようにしました。
mkbm.c

コード:

#include <stdio.h>    // fopen, fclose, fscanf, fwrite, fputc
#include <windows.h>  // BITMAPFILEHEADER, BITMAPINFOHEADER
 
#define HEADER_SIZE (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER))
 
int main(int argc, char *argv[])
{
    FILE *fin, *fout;
    int width, height, widthByte, padding, dataSize, byte, i, j;
    BITMAPFILEHEADER bf = { 0 };
    BITMAPINFOHEADER bi = { 0 };

    if (argc < 3) return printf("usage: %s infile outfile\n", argv[0]), 1;
    fin = fopen(argv[1], "r");
    if (!fin) return printf("can't open %s\n", argv[1]), 2;
    fout = fopen(argv[2], "wb");
    if (!fout) return printf("can't create %s\n", argv[2]), 3;

    if (fscanf(fin, "%d%d", &width, &height) != 2)
        return puts("width, height: read error"), 4;
    widthByte = width * 3;
    padding = ((widthByte + 3) & ~3) - widthByte;
    dataSize = (widthByte + padding) * height;
 
    bf.bfType = 0x4d42; // "BM" little endian
    bf.bfSize = HEADER_SIZE + dataSize;
    bf.bfOffBits = HEADER_SIZE;
 
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = width;
    bi.biHeight = height;
    bi.biPlanes = 1;
    bi.biBitCount = 24;
    bi.biSizeImage = dataSize;
 
    fwrite(&bf, 1, sizeof bf, fout);
    fwrite(&bi, 1, sizeof bi, fout);

    for (i = 0; i < height; i++) {
        for (j = 0; j < widthByte; j++) {
            if (fscanf(fin, "%2x", &byte) != 1)
                return puts("can't read image data"), 5;
            fputc(byte, fout);
        }
        for (j = 0; j < padding; j++) fputc(0, fout);
    }
    fclose(fout);
    fclose(fin);
    return 0;
}
3x3.txt

コード:

3 3
000000 0000ff 00ff00
00ffff ffffff ff0000
ff00ff ffff00 808080
実行例

コード:

C:\tmp\BM>mkbm 3x3.txt 3x3.bmp
できた 3x3.bmp をペイントで開いてみましょう。
上下は逆になります。
また、certutil -f -encodehex 3x3.bmp 3x3dmp.txt で
16進ダンプファイルを作り、それを見てもよいでしょう。

入力ファイルのデータは、16進2文字ずつ読み込むので
スペースや改行は適当に入れて構いません。
パディングは内部で計算するので、データには含めません。

かずま

Re: どこが間違っていますか?

#19

投稿記事 by かずま » 6年前

かずま さんが書きました:

コード:

    padding = ((widthByte + 3) & ~3) - widthByte;
padding の計算はもっと簡単にできます。

コード:

	padding = -widthByte & 3;

fabersid
記事: 42
登録日時: 6年前

Re: どこが間違っていますか?

#20

投稿記事 by fabersid » 6年前

かずま さんが書きました:ビットマップファイルというバイナリファイルを作りたいのに、
文字列のデータをプログラム内に作るという意味が理解できません。

No.9 のプログラムは無視されたようですね。
>文字列のデータをプログラム内に作るという意味が理解できません。
冗長性がありますがコードで書くよりも少なくとも
私は理解しやすかったからです。また、コードを参考に
今度は質問サイトを使わずにそのほかの
画像にも対応させたいため
定数部(BMなど)の変更を容易にしました。

>No.9 のプログラムは無視されたようですね。
すみませんまだ読んでません
プログラムを組むこととネットを見ることが
同時にできない環境で8割は数多くのエラーを
眺めて修正してという風にしてますので

このコメントを書き込んでいる媒体では
プログラミングができません。
フォーラムチェック用に借りました。

次にC言語開発ができるのは
早くて2月23日、遅くて4月といった具合です。
なので、コメントを読み動作を予想することしかできません。

かずま

Re: 先ほどの追記

#21

投稿記事 by かずま » 6年前

fabersid さんが書きました: 計算するといっても詰め物である00の数がわからない以上
ファイルとデータ本体の大きさがわかりません。
BM_maker.c

コード:

#include <stdio.h>
#include <string.h>  // strlen

typedef struct type_BMP {
    char H00[(2+1)*2]; //bfType         'As Integer 'ファイルタイプ
    char H02[(2+1)*4]; //bfSize         'As Long    'ファイルサイズ[byte]
    char H06[(2+1)*2]; //bfReserved1    'As Integer '予約領域1
    char H08[(2+1)*2]; //bfReserved2    'As Integer '予約領域2
    char H0A[(2+1)*4]; //bfOffBits      'As Long    'ファイル先頭から画像データまでのオフセット[byte]
    char H0E[(2+1)*4]; //biSize         'As Long    '情報ヘッダサイズ[byte]
    char H12[(2+1)*4]; //biWidth        'As Long    '画像の幅[ピクセル]
    char H16[(2+1)*4]; //biHeight       'As Long    '画像の高さ[ピクセル]
    char H1A[(2+1)*2]; //biPlanes       'As Integer 'プレーン数
    char H1C[(2+1)*2]; //biBitCount     'As Integer '色ビット数[bit]
    char H1E[(2+1)*4]; //biCompression  'As Long    '圧縮形式
    char H22[(2+1)*4]; //biSizeImage    'As Long    '画像データサイズ[byte]
    char H26[(2+1)*4]; //biXPixPerMeter 'As Long    '水平解像度[dot/m]
    char H2A[(2+1)*4]; //biYPixPerMeter 'As Long    '垂直解像度[dot/m]
    char H2E[(2+1)*4]; //biClrUsed      'As Long    '格納パレット数[使用色数]
    char H32[(2+1)*4]; //biCirImportant 'As Long    '重要色数
} BMP;
 
BMP BMP_set(int, char []);
 
int main(int argc, char *argv[])
{
    BMP outFile = BMP_set(argc, argv[1]);
    printf("%s\n%s\t<―\n%s\n%s\n%s\n%s\n%s\n%s\n"
        "%s\t\t<―\n%s\t\t<―\n%s\n%s\t<―\n%s\n%s\n%s\n%s\n",
        outFile.H00, outFile.H02, outFile.H06,
        outFile.H08, outFile.H0A, outFile.H0E,
        outFile.H12, outFile.H16, outFile.H1A,
        outFile.H1C, outFile.H1E, outFile.H22,
        outFile.H26, outFile.H2A, outFile.H2E,
        outFile.H32);
    return 0;
}

void set4(char *p, int x)
{
    sprintf(p, "%02x %02x %02x %02x",
        x & 0xff, x>>8 & 0xff, x>>16 & 0xff, x>>24 & 0xff);
}
 
BMP BMP_set(int argc, char argv1[])
{
    static BMP outFile = {
        "42 4d",         //2 ファイルタイプ
        "00 00 00 00",   //4 ファイルサイズ[byte]
        "00 00",         //2 予約領域1
        "00 00",         //2 予約領域2
        "36 00 00 00",   //4 ファイル先頭から画像データまでのオフセット[byte]
        "28 00 00 00",   //4 情報ヘッダサイズ[byte]
        "00 00 00 00",   //4 画像の幅[ピクセル]
        "00 00 00 00",   //4 画像の高さ[ピクセル]
        "01 00",         //2 プレーン数
        "18 00",         //2 色ビット数[bit]
        "00 00 00 00",   //4 圧縮形式
        "00 00 00 00",   //4 画像データサイズ[byte]
        "00 00 00 00",   //4 水平解像度[dot/m]
        "00 00 00 00",   //4 垂直解像度[dot/m]
        "00 00 00 00",   //4 格納パレット数[使用色数]
        "00 00 00 00",   //4 重要色数
    };
    int row = argc - 1;
    int col = row;
    int colByte = col * 3;       // RGB24ビット、3バイト/ピクセル
    int padding = -colByte & 3;  // 4の倍数にするための詰め物(0~3)
    int dataSize = (colByte + padding) * row;
    int fileSize = 14 + 40 + dataSize;
 
    if (argc > 1 && strlen(argv1) != (colByte + padding) * 2u)
        printf("'%s': invalid length\n", argv1);

    set4(outFile.H02, fileSize);
    set4(outFile.H12, col);
    set4(outFile.H16, row);
    set4(outFile.H22, dataSize);

    return outFile;
}
実行例

コード:

C:\tmp\BM>BM_maker ffffff00
42 4d
3a 00 00 00     <―
00 00
00 00
36 00 00 00
28 00 00 00
01 00 00 00
01 00 00 00
01 00           <―
18 00           <―
00 00 00 00
04 00 00 00     <―
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00

C:\tmp\BM>BM_maker ffffffffffffffffff000000 ffffffffffffffffff000000 ffffffffffffffffff000000
42 4d
5a 00 00 00     <―
00 00
00 00
36 00 00 00
28 00 00 00
03 00 00 00
03 00 00 00
01 00           <―
18 00           <―
00 00 00 00
24 00 00 00     <―
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00

このあと、どうやってビットマップファイルの作るんでしょうか?

かずま

Re: 先ほどの追記

#22

投稿記事 by かずま » 6年前

かずま さんが書きました: このあと、どうやってビットマップファイルの作るんでしょうか?
こうやってビットマップファイルを作っては、いかがでしょうか?

コード:

void put2(FILE *fp, const char *p)
{
    int x[2];
    sscanf(p, "%x%x", x, x + 1);
    fputc(x[0], fp), fputc(x[1], fp);
}

void put4(FILE *fp, const char *p)
{
    int x[4], i;
    sscanf(p, "%x%x%x%x", x, x + 1, x + 2, x + 3);
    for (i = 0; i < 4; i++) fputc(x[i], fp);
}

int BMP_put(const BMP *bmp, const char *name, int argc, char *argv[])
{
    int x, i;
    char *p;
    FILE *fp = fopen(name, "wb");
    if (!fp) return printf("can't create %s\n", name), 3;

    put2(fp, bmp->H00); put4(fp, bmp->H02); put2(fp, bmp->H06);
    put2(fp, bmp->H08); put4(fp, bmp->H0A); put4(fp, bmp->H0E);
    put4(fp, bmp->H12); put4(fp, bmp->H16); put2(fp, bmp->H1A);
    put2(fp, bmp->H1C); put4(fp, bmp->H1E); put4(fp, bmp->H22);
    put4(fp, bmp->H26); put4(fp, bmp->H2A); put4(fp, bmp->H2E);
    put4(fp, bmp->H32);

    for (i = argc; --i > 0; )
        for (p = argv[i]; p[0] && p[1]; p += 2) {
            if (sscanf(p, "%2x", &x) != 1)
                return puts("image data: read error"), 4;
            fputc(x, fp);
        }
    fclose(fp);
    return 0;
}
そして、main の return 0; を次のように変更します。

コード:

    return BMP_put(&outFile, "out.bmp", argc, argv);
出力ファイルの名前が固定ですが、コマンドラインの
引数で指定したいのなら、さらに変更が必要です。

返信

“C言語何でも質問掲示板” へ戻る