如何在C中创建位图并使用gcc进行编译

时间:2017-10-20 20:07:00

标签: c gcc bitmap

我决定学习C,我尝试按照本教程enter image description here

但是当我尝试使用gcc编译我的代码时,这是> gcc -Wall testc o app

他不知道type_rgb,我可以定义这种类型以及如何定义?我的代码在哪里?

#include <stdio.h>


struct rgb_data {
  float r, g, b;
};

void save_bitmap( const char *file_name, int width, int height, int dpi, type_rgb  *pixel_data); 
/*
 next steps of the tutorial
*/

rgb_data *pixels = new rgb_data[width * height];

for( int x = 0; x < width; x++)
  {
    for(int y = 0; y < height; y++)
        int a = y * width +x; 
          {

            if ((x > 50 && x < 350) && (y > y && y < 350))
              {
                pixels[a].r = 255;
                pixels[a].g = 255;
                pixels[a].b = 0;
              }else{
                pixels[a].r = 55;
                pixels[a].g = 55;
                pixels[a].b = 55;
              }

     }
}

save_bitmap("black_border.bmp", width, height, dpi, pixels);

1 个答案:

答案 0 :(得分:0)

位图文件格式相当复杂。这不是学习C的最好方法。最好从更简单的东西开始。

话虽如此,位图格式以位图头BITMAPFILEHEADER结构开始,结构长度为14个字节,后跟BITMAPINFOHEADER结构,长度为40个字节。这些结构在"Windows.h"

中定义

您必须在这些结构中写入各种信息,并在写入实际像素之前将它们写入文件。

您可以拥有1,4,8,16,24和32位位图。这是读取32位位图的示例。此代码假定sizeof(short)为2,sizeof(int)为4。

int main()
{
    int row, column;
    int width = 100;
    int height = 100;
    int size = width * height * 4; //for 32-bit bitmap only

    char header[54] = { 0 };
    strcpy(header, "BM");
    memset(&header[2],  (int)(54 + size), 1);
    memset(&header[10], (int)54, 1);//always 54
    memset(&header[14], (int)40, 1);//always 40
    memset(&header[18], (int)width, 1);
    memset(&header[22], (int)height, 1);
    memset(&header[26], (short)1, 1);
    memset(&header[28], (short)32, 1);//32bit
    memset(&header[34], (int)size, 1);//pixel size

    unsigned char *pixels = malloc(size);
    for(row = height - 1; row >= 0; row--) {
        for(column = 0; column < width; column++) {
            int p = (row * width + column) * 4;
            pixels[p + 0] = 64; //blue
            pixels[p + 1] = 128;//green
            pixels[p + 2] = 192;//red
        }
    }

    FILE *fout = fopen("32bit.bmp", "wb");
    fwrite(header, 1, 54, fout);
    fwrite(pixels, 1, size, fout);
    free(pixels);
    fclose(fout);
    return 0;
}

注意第一个像素是蓝色,然后是绿色和读取。最后一个像素不用于32位位图。高度也从下到上。这是位图的另一个奇怪特征。 24位位图更复杂,因为它们需要填充。 8位和更低位需要额外的调色板。

struct rgb_data {
  float r, g, b;
};

float不是像素的正确类型。每种颜色从0到255.这适合unsigned char。你需要

struct rgb_data {
  unsigned r, g, b, alpha;
};

alpha是32位位图的额外字节(我们不会使用)。请注意,此结构的大小为4.您可以将其分配为

struct rgb_data *rgb = malloc(size);

现在您可以按如下方式访问像素:

int p = (row * width + column);
rgb[p].r = 255;
rgb[p].g = 0;
rgb[p].b = 0;
...
fwrite(rgb, 4, width * height, fout);