C ++ создает растровый файл - не поддерживается для просмотра

0

Я настраиваю программу для графики, но для моего стартового тестового примера для создания растрового изображения. При попытке просмотра созданного образа я, кажется, получаю ошибку "файл не поддерживается". Сначала это было в bitmap.h при unsigned char color[3] = {(char)floor(blue), (char)floor(green), (char)floor(red)}; думая, что бросок должен быть int, но это не сдвинулось с места.

color.h

#ifndef _COLOR_H
#define _COLOR_H

class Color {
public: 
    double r, g, b;

    Color() {};
    ~Color() {};
    Color(double _r, double _g, double _b) : r(_r/255), g(_g/255), b(_b/255) {}

    // omitted operator overloads and print method not used in test case
};

#endif

bitmap.h

#ifndef _BITMAP_H
#define _BITMAP_H

void savebmp(const char* filename, int width, int height, int dpi, Color* data) {
    FILE *f;
    int k = width * height;
    int s = 4 * k;
    int filesize = 54 + s;

    int m = static_cast<int>(39.375);
    int ppm = dpi * m; // pixels per meter

    unsigned char bmpfileheader[14] = { 
        'B', 'M', 0, 0, 0, 0, 0, 
         0, 0, 0, 0, 0, 0, 0 
    };

    unsigned char bmpinfoheader[40] = {
        40, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 1, 0, 24, 0
    };


    // Unsure about this implementation - read more about bitmap creading
    bmpfileheader[2] = (unsigned char)(filesize);
    bmpfileheader[3] = (unsigned char)(filesize >> 8);
    bmpfileheader[4] = (unsigned char)(filesize >> 16);
    bmpfileheader[5] = (unsigned char)(filesize >> 24);

    bmpinfoheader[4] = (unsigned char)(width);
    bmpinfoheader[5] = (unsigned char)(width >> 8);
    bmpinfoheader[6] = (unsigned char)(width >> 16);
    bmpinfoheader[7] = (unsigned char)(width >> 24);

    bmpinfoheader[8] = (unsigned char)(height);
    bmpinfoheader[9] = (unsigned char)(height >> 8);
    bmpinfoheader[10] = (unsigned char)(height >> 16);
    bmpinfoheader[11] = (unsigned char)(height >> 24);

    bmpinfoheader[21] = (unsigned char)(s);
    bmpinfoheader[22] = (unsigned char)(s >> 8);
    bmpinfoheader[23] = (unsigned char)(s >> 16);
    bmpinfoheader[24] = (unsigned char)(s >> 24);

    bmpinfoheader[25] = (unsigned char)(ppm);
    bmpinfoheader[26] = (unsigned char)(ppm >> 8);
    bmpinfoheader[27] = (unsigned char)(ppm >> 16);
    bmpinfoheader[28] = (unsigned char)(ppm >> 24);

    bmpinfoheader[29] = (unsigned char)(ppm);
    bmpinfoheader[30] = (unsigned char)(ppm >> 8);
    bmpinfoheader[31] = (unsigned char)(ppm >> 16);
    bmpinfoheader[32] = (unsigned char)(ppm >> 24);

    fopen_s(&f, filename, "wb");
    fwrite(bmpfileheader, 1, 14, f);
    fwrite(bmpinfoheader, 1, 40, f);

    for (int i = 0; i < k; i++) {
        Color rgb = data[i];

        double red = data[i].r * 255;
        double green = data[i].g * 255;
        double blue = data[i].b * 255;

        unsigned char color[3] = {(char)floor(blue), (char)floor(green), (char)floor(red)};

        fwrite(color, 1, 3, f);
    }
    fclose(f);
}

#endif

main.cpp

#include <iostream>
#include <fstream>
#include <cmath>
#include "color.h"
#include "bitmap.h"

int element;

int main(int argc, char **argv) {
    int dpi = 72;
    int width = 640;
    int height = 480;
    int n = width * height;
    Color *pixels = new Color[n]; // look into smart pointers

    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
            // element position in pixels array
            element = y * width + x;

            pixels[element] = Color(23, 76, 210);
        }
    }

    savebmp("practice.bmp", width, height, dpi, pixels);
    // should generate solid blue image

    std::getchar();

    return 0;
}
  • 0
    У вас должно быть хорошее изображение для сравнения с тем, которое вы сгенерировали с помощью вашей программы, чтобы увидеть, что именно является неправильным (используйте шестнадцатеричный просмотрщик или редактор). Во-вторых, есть буквально тысячи примеров написания базовых растровых изображений на C ++ (даже C) - почему бы сначала не использовать рабочий пример для создания своего класса?
  • 0
    взял ваш код и создал изображение, которое может быть открыто IrfanView. Изображение 24 BPP и все синее. Какую программу просмотра изображений вы используете, чтобы открыть изображение?
Теги:
bitmap

1 ответ

0

Пара вещей:

memset эти байтовые массивы до нулей, если вы оставляете дыры. Вы уверены, что идет в каждом байте? Вы должны быть.

Я могу только предположить, что вы BITMAPINFOHEADER структуру BITMAPINFOHEADER. Почему бы не использовать структуру? Даже если у вас нет заголовка, вы можете определить его самостоятельно и сэкономить путаницу с массивом байтов.

Далее, начиная с строки bmpinfoheader[21] = (unsigned char)(s); у вас, кажется, есть один за другим. Поле biSizeImage начинается с byte с индексом 20, а не 21. Последующее действие продолжается в вашем коде.

Наконец, пиксели сохраняются по строкам, а затем дополняются к 4-байтовому выравниванию. Вы перечисляете pixels по высоте во внутреннем цикле, поэтому вместо этого вы переходите от столбца к столбцу. И не забывайте прокладку! Вы можете рассчитать, сколько байтов вам нужно использовать с помощью:

4 - (sizeOfRowInBytes % 4)

Надеюсь, это поможет вам. Вы можете найти эту страницу в Википедии полезной.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню