微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将 8 位灰度 .BMP 图像转换为 1 位 .BMP 图像的困难

如何解决将 8 位灰度 .BMP 图像转换为 1 位 .BMP 图像的困难

我正在寻找一种将 256 个灰度级的 BMP 图像转换为 1 位 BMP 图像的方法。转换规则是,对于 0 - 127 的灰度级,该位应该是 0,从 128 - 255 的灰度级应该是 1。到目前为止,我已经尝试用 C 编写程序。问题是即使我更改了信息标题为 1 BBP,输出是黑色图像(顺便说一句,我使用 Lena 作为输入文件),好像颜色深度仍然是 8 位(而在属性中它说的是 1 位)。

我尝试在十六进制编辑器中打开 BMP 文件,看到像素数据已按预期更改为 0 和 1,并且输入和输出文件标题除了颜色深度之外都相同。我错过了什么吗?我需要对图像进行哪些更改才能显示预期内容

link

这是我的程序:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#pragma pack(1)     //avoid padding in a struct    

typedef uint8_t  BYTE;
typedef uint32_t DWORD;
typedef int32_t  LONG;
typedef uint16_t WORD;

typedef struct 
{
    WORD Signature;
    DWORD fSize;
    WORD fReserved_1;
    WORD fReserved_2;
    DWORD fOffset;
} BITMAP_HEADER;

typedef struct 
{
    DWORD Size;
    LONG  Width;
    LONG  Height;
    WORD  Planes;
    WORD  BitsPerPixel;
    DWORD Compression;
    DWORD imgSize;
    LONG  ResX;
    LONG  ResY;
    DWORD Color;
    DWORD ImpColor;
} INFO_HEADER;

typedef struct
{
    BYTE rgbtBlue;    //since I'm only dealing with 8-bit colour depth 
                      //so only one value is needed I guess?
    // BYTE rgbtGreen;
    // BYTE rgbtRed;
} RGBTRIPLE;

void BinaryConvert(DWORD height,DWORD width,RGBTRIPLE img[height][width]);

int main()
{
    FILE* fp,*cp;
    fp = fopen("Resources/test.bmp","rb");     //bmp is binary file,therefore use "rb" permission
    cp = fopen("Resources/output.bmp","wb");

    BITMAP_HEADER fheader;
    INFO_HEADER   fInfo;
    
    //read headers
    fread(&fheader,sizeof(BITMAP_HEADER),1,fp);
    fread(&fInfo,sizeof(INFO_HEADER),fp);

    int width = fInfo.Width;
    int height = fInfo.Height;

    int padding = (4 - (width * sizeof(RGBTRIPLE)) % 4) % 4;
    
    RGBTRIPLE (*image)[width] = calloc(height,width * sizeof(RGBTRIPLE));

    //read pixel data
    for (int i = 0; i < height; i++)
    {
        fread(image[i],sizeof(RGBTRIPLE),width,fp);
        fseek(fp,padding,SEEK_CUR);      //skip over padding
    }

    //coonvert grey levels into 0 and 1
    BinaryConvert(height,image);

    //modify file header
    fInfo.noBitsPerPixel = 1;

    //write headers into output file
    fseek(cp,SEEK_SET);
    fwrite(&fheader,cp);
    fwrite(&fInfo,cp);
  
    //write pixel data into output file
    for (int i = 0; i < height; i++)
    {
       fwrite(image[i],cp);
       for (int k = 0; k < padding; k++)
       {
           fputc(0x00,cp);
       }
    }

    fclose(cp);
    fclose(fp);   
}
   
void BinaryConvert(DWORD height,RGBTRIPLE img[height][width])
{
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            if (img[i][j].rgbtBlue <= 127 && img[i][j].rgbtBlue >=0)
            {
                img[i][j].rgbtBlue = 0;
            }
            else if (img[i][j].rgbtBlue <= 255 && img[i][j].rgbtBlue >= 128)
                img[i][j].rgbtBlue = 1;
        }
    }
}

Input file (lena.bmp). (257 KB)

Result from program (257 KB)

解决方法

您需要使用 255 而不是 1。那是白色的颜色

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。