【问题标题】:Writing bitmap in C用 C 写位图
【发布时间】:2018-12-23 09:19:44
【问题描述】:

这是我的位图图像代码,但它不起作用,我不知道为什么。我以前做过同样的事情,但我正在阅读原始位图,我只需要更改它的颜色。该代码的想法完全相同,并且当时确实有效,但是对于从 0 读取图像似乎不起作用。我在互联网上搜索了很多答案,我认为这可能是来自标题的数据或有关填充的问题。你能帮帮我吗?

标题:

#pragma pack(1)

struct bmp_fileheader
{
unsigned char  fileMarker1; /* 'B' */
unsigned char  fileMarker2; /* 'M' */
unsigned int   bfSize; /* File's size */
unsigned short unused1;
unsigned short unused2;
unsigned int   imageDataOffset; /* Offset to the start of image data */
};

struct bmp_infoheader
{
unsigned int   biSize; /* Size of the info header - 40 bytes */
signed int     width; /* Width of the image */
signed int     height; /* Height of the image */
unsigned short planes;
unsigned short bitPix;
unsigned int   biCompression;
unsigned int   biSizeImage; /* Size of the image data */
int            biXPelsPerMeter;
int            biYPelsPerMeter;
unsigned int   biClrUsed;
unsigned int   biClrImportant;
};

#pragma pack()

代码:

#include <stdio.h>
#include <stdlib.h>
#include "bmp_header.h"

typedef struct {
unsigned char b;
unsigned char g;
unsigned char r;
}rgb;
int main() {

int i, j, k;
struct bmp_fileheader a;
struct bmp_infoheader b;
FILE * p = fopen("img.bmp", "wb");


a.fileMarker1 = 'B';
a.fileMarker2 = 'M';
a.unused1=0;
a.unused2=0;
a.bfSize = 54+3*40*40;
a.imageDataOffset=54;


b.biSize = 40;
b.width = 40;
b.width = 40;
b.planes = 1;
b.bitPix = 24;
b.biCompression = 0;
b.biSizeImage = 4*40*40;
b.biXPelsPerMeter = 0;
b.biYPelsPerMeter = 0;
b.biClrUsed = 0;
b.biClrImportant = 0;

rgb matrix[40][40];

for (i = 0; i < 10; i++) {
    for (j = 0; j < 40; j++) {
        matrix[i][j].b = 255;
        matrix[i][j].g = 255;
        matrix[i][j].r = 255;
    }
}

for (i = 10; i < 30; i++) {
    for (j = 0; j < 40; j++) {
        if (j < 10 || j > 29) {
            matrix[i][j].b = 255;
            matrix[i][j].g = 255;
            matrix[i][j].r = 255;
        } else {
            matrix[i][j].b = 255;
            matrix[i][j].g = 255;
            matrix[i][j].r = 0;
        }
    }
}

for (i = 30; i < 40; i++) {
    for (j = 0; j < 40; j++) {
        matrix[i][j].b = 255;
        matrix[i][j].g = 255;
        matrix[i][j].r = 255;
    }
}

fwrite( & a, sizeof(a), 1, p);
fwrite( & b, sizeof(b), 1, p);

int t = (4 - (40 * 3)%4)%4;//padding equation found on the internet
for(i = 0; i < 40; i++){
    for(j = 0; j < 40; j++)
        fwrite(&matrix[i][j], sizeof(matrix[i][j]), 1, p);

    for(k = 0; k < t; k++){
        putc(0,p); //padding
    }

}
fclose(p);
}

【问题讨论】:

  • "...但它不起作用..." 是一个非常广泛的错误描述。你能提供更多细节吗?
  • 标题的结尾不应该是#pragma pack(pop) 而不是#pragma pack()
  • 另外,你写的是matrix,但你没有把#pragma pack放在rgb struct周围
  • 这个b.width = 40; b.width = 40; ---> b.width = 40; b.height = 40;

标签: c image bitmap


【解决方案1】:

扫描线大小计算如下:

#define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4)

biSizeImage 字段计算为:

b.biSizeImage= WIDTHBYTES(xRes*24) * yRes;

24 是每个像素的位数。

您还设置了两次b.width。第二个应该是height


此外,infoheader 字段必须计算为(适应您的结构命名):
fheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + 0/*no palette for 24 bits color*/;
fheader.bfSize = fheader.bfOffBits + iheader.biSizeImage;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    • 1970-01-01
    • 1970-01-01
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多