【问题标题】:generate monochrome bitmap image using c使用 c 生成单色位图图像
【发布时间】:2019-07-21 15:53:23
【问题描述】:

我正在编写代码以从数组中生成单色 bmp 图像。有很多工具可以生成 bmp 到数组,但我希望它以相反的方式。我发现了很多代码,但它是彩色图像。 这是我正在尝试的代码...

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <malloc.h>
#define _height 64
#define _width 128
#define _bitsperpixel 1
#define _planes 1
#define _compression 0
#define _pixelbytesize _height*_width*_bitsperpixel/8
#define _filesize _pixelbytesize+sizeof(bitmap)
#define _xpixelpermeter 0x130B //2835 , 72 DPI
#define _ypixelpermeter 0x130B //2835 , 72 DPI
#define pixel 0x55
#pragma pack(push,1)

unsigned char arr[8192]={0};

typedef struct{
    uint8_t signature[2];
    uint32_t filesize;
    uint32_t reserved;
    uint32_t fileoffset_to_pixelarray;
} fileheader;
typedef struct{
    uint32_t dibheadersize;
    uint32_t width;
    uint32_t height;
    uint16_t planes;
    uint16_t bitsperpixel;
    uint32_t compression;
    uint32_t imagesize;
    uint32_t ypixelpermeter;
    uint32_t xpixelpermeter;
    uint32_t numcolorspallette;
    uint32_t mostimpcolor;
} bitmapinfoheader;
typedef struct {
    fileheader fileheader;
    bitmapinfoheader bitmapinfoheader;
} bitmap;
#pragma pack(pop)

int main (int argc , char *argv[]) {
int i;
    FILE *fp = fopen("test.bmp","wb");
    bitmap *pbitmap  = (bitmap*)calloc(1,sizeof(bitmap));
    uint8_t *pixelbuffer = (uint8_t*)malloc(_pixelbytesize);
    strcpy(pbitmap->fileheader.signature,"BM");
    pbitmap->fileheader.filesize = _filesize;
    pbitmap->fileheader.fileoffset_to_pixelarray = sizeof(bitmap);
    pbitmap->bitmapinfoheader.dibheadersize =sizeof(bitmapinfoheader);
    pbitmap->bitmapinfoheader.width = _width;
    pbitmap->bitmapinfoheader.height = _height;
    pbitmap->bitmapinfoheader.planes = _planes;
    pbitmap->bitmapinfoheader.bitsperpixel = _bitsperpixel;
    pbitmap->bitmapinfoheader.compression = _compression;
    pbitmap->bitmapinfoheader.imagesize = _pixelbytesize;
    pbitmap->bitmapinfoheader.ypixelpermeter = _ypixelpermeter ;
    pbitmap->bitmapinfoheader.xpixelpermeter = _xpixelpermeter ;
    pbitmap->bitmapinfoheader.numcolorspallette = 0;
    fwrite (pbitmap, 1, sizeof(bitmap),fp);
    for(i=0;i<8192;i++)
    {
    pixelbuffer[i] = arr[i];
}
 //   memset(pixelbuffer,pixel,_pixelbytesize);
    fwrite(pixelbuffer,1,_pixelbytesize,fp);
    fclose(fp);
    free(pbitmap);
    free(pixelbuffer);
}

我给每个像素的位数是 1 位(我想要黑色或白色),并且不确定必须更改的其他参数。

如果我使用 _bitsperpixel 作为 24,那么它工作正常,但如果我指定为 1,那么它就会崩溃..

【问题讨论】:

  • OT:关于#define _height 64 1) 不要使用前导下划线编译器对前导下划线有特殊用途。 2) 一般而言,#define 名称和结构名称通常以全大写形式编写,因此它们脱颖而出
  • OT: about: typedef struct { fileheader fileheader; bitmapinfoheader bitmapinfoheader; } bitmap; 1) 这使得结构匿名,因为结构没有tag 名称。结果是难以通过调试器显示结构中的字段,因为大多数调试器使用 tag 名称 2) 使字段名称与类型名称相同是一种非常糟糕的编程范例,并导致人类读者感到困惑跨度>
  • OT: about: FILE *fp = fopen("test.bmp","wb"); 在调用(大多数)C 库函数(包括fopen())后,始终检查返回值(在这种情况下为 !=NULL)以确保操作成功。如果不成功,则调用perror( "fopen failed" );,以便您的错误消息和系统认为该功能失败的文本原因stderr
  • OT:关于; bitmap *pbitmap = (bitmap*)calloc(1,sizeof(bitmap));uint8_t *pixelbuffer = (uint8_t*)malloc(_pixelbytesize); 1) 这些函数返回一个类型为 void* 的值,该值可以分配给任何指针。强制转换只会使代码混乱 2) 调用这些函数时,始终检查 (!=NULL) 返回值以确保操作成功。
  • 注:黑白图像的最小像素值为8位,有效值为0xff0x00

标签: c bitmap bmp


【解决方案1】:

_bitsperpixel == 1,然后_pixelbytesize == 1024。您的循环一直运行到8192,因此写入超出了分配的内存。

根据您在arr 中存储的内容,您应该将循环的迭代次数减少到_pixelbytesize,或者将arr 中的字节转换为位:

for(int i = 0; i < _pixelbytesize; ++i)
{
    uint8_t b = 0;
    for(int j = 0; j < 8; ++j)
        b |= arr[8*i + j] >> 7 << j;
    pixelbuffer[i] = b;
}

请注意,这是一个简单的代码,仅适用于可被 8 整除的图像宽度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-12
    相关资源
    最近更新 更多