Cam Nguyễn Ответов: 1

Как читать RGB и записывать BMP файл


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define TRUE 1
typedef unsigned char onebyte; // định nghĩa unsigned char là onebyte  
typedef short twobyte; // định nghĩa short là twobyte
typedef long fourbyte; // định nghĩa unsigned long là fourbyte

typedef struct {
    /* màu trong bitmap là BGR*/
    onebyte B; //blue
    onebyte G; //green
    onebyte R; //read
} Color;

typedef struct {
    /* BitMap header 14 byte */
    twobyte type; // 2 byte - Mã nhận dạng file bitmap
    fourbyte filesize; // 4 byte - Kích thước của file tính theo byte
    fourbyte reserved1; // 4 byte - Dự trữ, không sử dụng
    fourbyte reserved2; // 4 byte - Dự trữ, không sử dụng
    fourbyte offset; // 4 byte - Vị trí bắt đầu dữ liệu ảnh
    /* ***  bitmap info 40 byte */
    fourbyte biSize; // 4 byte - Kích thước phần Information (luôn là40)
    fourbyte biWidth; // 4 byte - Chiều rộng ảnh tính bằng pixel
    fourbyte biHeight; // 4 byte - Chiều cao ảnh tính bằng pixel
    fourbyte biPlanes; // 2 byte - Số plane màu (thường là 1)
    twobyte biBitCount; // 2 byte - bit mỗi điểm ảnh, mang các giá trị 1,4,8 hoặc 24 bit
    fourbyte biCompression; // 4 byte - Kiểu nén (0: không nén);(1:run_lenght(8 bit/pixel));(2:run_length(4 bit/pixel))
    fourbyte biSizeImage; // 4 byte - Kích thước phần dữ liệu ảnh tính theo byte
    fourbyte biXPelsPerMeter; // 4 byte - Độ phân giải ngang (metter)
    fourbyte biYPelsPerMeter; // 4 byte - Độ phân giải dọc (metter)
    fourbyte biClrUsed; // 4 byte - Số màu sử dụng (= 0 nếu là tất cả)
    fourbyte biClrImportant; // 4 byte - Số màu quan trọng (= 0 nếu là tất cả)
} BitMap;

void read_BMPinfo(char*filename, BitMap Header);
void write_bmpfile(char*outfilename, BitMap Header);

int main(int argc, char** argv) {
    BitMap _Header;
    Color  _Pix;
    FILE *fft;
    char infile[21]; //khai báo string filename
    char outfile[25] = "grayphoto.bmp";
restart:
    printf(" \n Nhap ten file (khong nhap dinh dang duoi): ");
    fflush(stdin); //xóa bộ nhớ đệm từ bàn phím
    scanf("%21s", &infile); //đọc ký tự vừa nhập từ bàn phím
    strcat(infile, ".bmp");
    fft = fopen(infile, "rb");
    if (fft == NULL) {
        printf(" \n file not found \n");
        goto restart;
    }
    read_BMPinfo(infile, _Header);
    write_bmpfile(char*outfilename, BitMap Header)
    getch();
    return (0);
}

void write_bmpfile(char*outfilename, BitMap Header) {
    int i, j, ipos;
    int bytesPerLine;
    unsigned char *line;
    /* The length of each line must be a multiple of 4 bytes */
    bytesPerLine = (3 * (Header.biWidth + 1) / 4) * 4;

    FILE*file = fopen(outfilename, "wb");

    fwrite(&Header.type, sizeof (Header), 1, file);
    fwrite(&Header.filesize, sizeof (Header), 1, file);
    fwrite(&Header.reserved1, sizeof (Header), 1, file);
    fwrite(&Header.reserved1, sizeof (Header), 1, file);
    fwrite(&Header.offset, sizeof (Header), 1, file);
    fwrite(&Header.biSize, sizeof (Header), 1, file);
    fwrite(&Header.biWidth, sizeof (Header), 1, file);
    fwrite(&Header.biHeight, sizeof (Header), 1, file);
    fwrite(&Header.biPlanes, sizeof (Header), 1, file);
    fwrite(&Header.biBitCount, sizeof (Header), 1, file);
    fwrite(&Header.biCompression, sizeof (Header), 1, file);
    fwrite(&Header.biSizeImage, sizeof (Header), 1, file);
    fwrite(&Header.biXPelsPerMeter, 4, 1, file);
    fwrite(&Header.biYPelsPerMeter, 4, 1, file);
    fwrite(&Header.biClrUsed, 4, 1, file);
    fwrite(&Header.biClrImportant, 4, 1, file);
    fclose(file);
    return;
}

void read_BMPinfo(char*filename, BitMap Header) {

    FILE*BMPFile = fopen(filename, "rb");

    memset(&Header, 0, sizeof (Header));
    fread(&Header.type, 2, 1, BMPFile);
    fread(&Header.filesize, 4, 1, BMPFile);
    fread(&Header.reserved1, 2, 1, BMPFile);
    fread(&Header.reserved2, 2, 1, BMPFile);
    fread(&Header.offset, 4, 1, BMPFile);
    fread(&Header.biSize, 4, 1, BMPFile);
    fread(&Header.biWidth, 4, 1, BMPFile);
    fread(&Header.biHeight, 4, 1, BMPFile);
    fread(&Header.biPlanes, 2, 1, BMPFile);
    fread(&Header.biBitCount, 2, 1, BMPFile);
    fread(&Header.biCompression, 4, 1, BMPFile);
    fread(&Header.biSizeImage, 4, 1, BMPFile);
    fread(&Header.biXPelsPerMeter, 4, 1, BMPFile);
    fread(&Header.biYPelsPerMeter, 4, 1, BMPFile);
    fread(&Header.biClrUsed, 4, 1, BMPFile);
    fread(&Header.biClrImportant, 4, 1, BMPFile);
    fclose(BMPFile);
    return;
}


Что я уже пробовал:

когда я пишу bmp-файл .Он не умеет читать.и я хочу, чтобы преобразовать RGB в серый.но я не могу.помогите мне

Patrice T

- когда я пишу bmp-файл .Он не умеет читать."
Задавать вопросы-это навык[^]

1 Ответов

Рейтинг:
1

Jochen Arndt

Вы только читаете и записываете заголовок, но не данные изображения.

Если вы прочитали заголовок, выделите буфер для данных изображения с размером bytesPerLine * height и считайте данные изображения в этот буфер. Затем вы можете преобразовать данные в буфере в серую шкалу. Наконец, запишите буфер в выходной файл после того, как заголовок был записан.

Есть также Ошибки при написании первых заголовочных элементов:

fwrite(&Header.type, sizeof (Header), 1, file);

Это приведет к записи большего количества байтов, чем вы, вероятно, хотите (размер заголовка вместо размера поля типа). Используйте это вместо этого (а также для всех других полей, где вы жестко закодировали размер):
fwrite(&Header.type, sizeof (Header.type), 1, file);


Наконец, ваш код не будет компилироваться без ошибок. Смотрите эту строку в main():
write_bmpfile(char*outfilename, BitMap Header)

Должно быть:
write_bmpfile(outfile, _Header);


Причин может быть еще больше ошибок. И несколько заметок:

Не используйте подчеркивание в качестве первого символа имен переменных или функций. Такие имена зарезервированы в C / C++.

Передавайте структуры по указателю (или ссылке с помощью C++), делая их const когда они не изменяются. Так что ваш write_bmpfile() функция может быть изменена на (без необходимости редактирования кода функции):
void write_bmpfile(const char *outfilename, const BitMap &Header);


Cam Nguyễn

спасибо, Арндт,я все исправлю