BMPファイルから各色を抽出するプログラム
プログラム
bmp_pix_dump.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
int read_start(FILE *fi) {
int start;
fseek(fi, 10, SEEK_SET);
fread(&start, 4, 1, fi);
return start;
}
int read_width(FILE *fi) {
int width;
fseek(fi, 18, SEEK_SET);
fread(&width, 4, 1, fi);
return width;
}
int read_height(FILE *fi) {
signed int height;
fseek(fi, 22, SEEK_SET);
fread(&height, 4, 1, fi);
return height;
}
int read_colorbit(FILE *fi) {
unsigned short bit;
fseek(fi, 28, SEEK_SET);
fread(&bit, 2, 1, fi);
return bit;
}
void read_datablock(FILE *fi, int width, int height, int data_start, int color_bit, int ft) {
int start, i;
char pix;
unsigned char pix_text;
start = data_start + (color_bit / 8);
if (ft == 1) {
printf("P2\n%d %d\n255\n", width, height);
} else if (ft == 2) {
printf("P5\n%d %d\n255\n", width, height);
}
for (i=0; i<(width*height)*3; i+=3) {
fseek(fi, i+start, SEEK_SET);
if (ft == 1) {
fread(&pix_text, 1, 1, fi);
printf("%d\n", pix_text);
} else {
fread(&pix, 1, 1, fi);
fwrite(&pix, 1, 1, stdout);
}
}
}
int main(int argc, char *argv[]) {
// ft: bin = 0, text_pgm = 1, bin_pgm = 2
int i, opt, w, h, data_start, pix_bit, color_bit, ft;
char *input_file = "", *color = "", *output_file_type = "";
FILE *fi;
opterr = 0;
while ((opt = getopt(argc, argv, "i:c:t:")) != -1) {
switch (opt) {
case 'i':
input_file = optarg;
break;
case 'c':
color = optarg;
break;
case 't':
output_file_type = optarg;
break;
default:
printf("Usage: %s [-i string] [-c {R|G|B}] [-t {bin|text_pgm|bin_pgm}] ...\n", argv[0]);
return -1;
}
}
fi = fopen(input_file, "r");
data_start = read_start(fi);
w = read_width(fi);
h = abs(read_height(fi));
pix_bit = read_colorbit(fi);
if (pix_bit != 24) {
printf("The input file must be 24-bit color.\n");
return -1;
}
if (strcmp(output_file_type, "bin") == 0) {
ft = 0;
} else if (strcmp(output_file_type, "text_pgm") == 0) {
ft = 1;
} else if (strcmp(output_file_type, "bin_pgm") == 0) {
ft = 2;
} else {
ft = 0;
}
if (strcmp(color, "R") == 0) {
color_bit = 16;
} else if (strcmp(color, "G") == 0) {
color_bit = 8;
} else if (strcmp(color, "B") == 0) {
color_bit = 0;
} else {
printf("Usage: %s [-i string] [-c {R|G|B}] [-t {bin|text_pgm|bin_pgm}] ...\n", argv[0]);
return -1;
}
read_datablock(fi, w, h, data_start, color_bit, ft);
return 0;
}
コンパイル
$ cc -o bmp_pix_dump bmp_pix_dump.c
使い方
$ bmp_pix_dump -i image.bmp -c R -t bin_pgm > image.RED.PGM
※ 詳しい使い方はプログラムを読んでください。