Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 位图将16 bpp转换为8 bpp_C_Bitmap - Fatal编程技术网

C 位图将16 bpp转换为8 bpp

C 位图将16 bpp转换为8 bpp,c,bitmap,C,Bitmap,我正在搜索将位图从16 bpp转换为8 bpp,我的灵感来自于我发现的将24 bpp转换为8 bpp的代码,我认为我的文件的编写是正确的(参见图),但该文件仍然无效 我认为数据存储在little endian中,但我不确定,因此我认为我的问题在于RGB颜色的提取,即使它不会使文件无效 #include <stdio.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #incl

我正在搜索将位图从16 bpp转换为8 bpp,我的灵感来自于我发现的将24 bpp转换为8 bpp的代码,我认为我的文件的编写是正确的(参见图),但该文件仍然无效

我认为数据存储在little endian中,但我不确定,因此我认为我的问题在于RGB颜色的提取,即使它不会使文件无效

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

#pragma pack(push, 2)
typedef struct {
    int16_t bfType;
    int32_t bfSize;
    int16_t bfReserved1;
    int16_t bfReserved2;
    int32_t bfOffBits;
} BITMAPFILEHEADER;

typedef struct {
    int32_t biSize;
    int32_t biWidth;
    int32_t biHeight;
    int16_t biPlanes;
    int16_t biBitCount;
    int32_t biCompression;
    int32_t biSizeImage;
    int32_t biXPelsPerMeter;
    int32_t biYPelsPerMeter;
    int32_t biClrUsed;
    int32_t biClrImportant;
} BITMAPINFOHEADER;
#pragma pack(pop)

int main()
{
    FILE* fin = fopen("SCR.bmp", "rb");
    FILE* fout = fopen("fout.bmp", "wb");
    if(!fin) { printf("fin error\n"); goto error; }
    if(!fout) { printf("fout error\n"); goto error; }

    BITMAPFILEHEADER bf;
    BITMAPINFOHEADER bi;
    fread(&bf, sizeof bf, 1, fin);
    fread(&bi, sizeof bi, 1, fin);

    if(sizeof bf != 14) { printf("Wrong pragma pack\n"); goto error; }
    if(sizeof bi != 40) { printf("Wrong pragma pack\n"); goto error; }
    if(bf.bfType != 0x4D42) { printf("not bmp, or not LE system\n"); goto error; }
    //if(bi.biSize != 40) { printf("Can't handle this bitmap format\n"); goto error; }
    //if(bi.biBitCount != 24) { printf("not 24-bit\n"); goto error; }

    int height = bi.biHeight;
    if(height < 0) height = -height;

    //width in bytes:
    int src_wb = ((bi.biWidth * 16 + 31) / 32) * 4;
    printf(" src wb =%d et width =%d et %d",src_wb,bi.biWidth,bi.biHeight);
    int dst_wb = ((bi.biWidth * 8 + 31) / 32) * 4;
    int src_size = src_wb * height;
    int dst_size = dst_wb * height;

    //allocate for source and destination
    uint8_t *src = malloc(src_size);
    uint8_t *dst = malloc(dst_size);

    //read pixels
    fread(src, 1, src_size, fin);

    //make gray scale color-table
    uint8_t clr[1024] = { 0 };
    for(int i = 0; i < 256; i++)
        clr[i * 4 + 0] = clr[i * 4 + 1] = clr[i * 4 + 2] = (uint8_t)i;

    for(int y = height - 1; y >= 0; y--)
    {
        for(int x = 0; x < bi.biWidth; x++)
        {
            uint8_t pt1 = src[y * src_wb + x * 2 + 0]; // first byte of pixel (LSB because little endian)
            uint8_t pt2 = src[y * src_wb + x * 2 + 1]; // second byte of pixel (MSB)
          //uint8_t grn = src[y * src_wb + x * 3 + 2];
            uint8_t red = pt2>>3;// 5 bit
            uint8_t grn = (uint8_t)((pt1 & 0xE)<<5)| (uint8_t)((pt2 &7)>>5) ;// 6 bit
            uint8_t blu = (pt1 & 0x11); // 5 bit
            uint8_t gry = (uint8_t)(.33 * red + .34 * grn + .33 * blu);
            dst[y * dst_wb + x] = gry; //this will match the index in color-table
        }
    }

    //modify bitmap headers
    bf.bfSize = 54 + 1024 + dst_size;
    bf.bfOffBits =54 +1024 ;
    bi.biBitCount = 8;
    bi.biSizeImage = dst_size;
    bi.biClrUsed=256;
    bi.biCompression=0;

    fwrite(&bf, sizeof bf, 1, fout);
    fwrite(&bi, sizeof bi, 1, fout);
    fwrite(clr, 1, 1024, fout);
    fwrite(dst, 1, dst_size, fout);
    free(src);
    free(dst);
error:
    fclose(fout);
    fclose(fin);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#pragma包(推送,2)
类型定义结构{
int16型;
int32_t bfSize;
国际储备1;
国际储备2;
int32_t bOffBits;
}位图文件头;
类型定义结构{
int32_t biSize;
int32_t双宽度;
int32_t biHeight;
国际16_t双翼飞机;
int16_t双比特计数;
int32_t双压缩;
int32_t biSizeImage;
int32_t双X渗透计;
int32_t双渗透计;
int32_t BICLRUSE;
int32_t BICLR很重要;
}位图信息头;
#布拉格语包(流行语)
int main()
{
文件*fin=fopen(“SCR.bmp”、“rb”);
文件*fout=fopen(“fout.bmp”、“wb”);
如果(!fin){printf(“fin error\n”);转到error;}
如果(!fout){printf(“fout error\n”);转到error;}
位图文件头;
BitMapInfo头bi;
fread(&bf,bf尺寸,1,fin);
fread(&bi,bi的尺寸,1,fin);
如果(sizeof bf!=14){printf(“错误的pragma pack\n”);转到错误;}
如果(sizeof bi!=40){printf(“错误的pragma pack\n”);转到错误;}
如果(bf.bfType!=0x4D42){printf(“非bmp,或非LE系统”);转到错误;}
//如果(bi.biSize!=40){printf(“无法处理此位图格式”\n”);转到错误;}
//如果(bi.bibibitcount!=24){printf(“非24位\n”);转到错误;}
int高度=bi.biHeight;
如果(高度<0)高度=-高度;
//以字节为单位的宽度:
int src_wb=((bi.biWidth*16+31)/32)*4;
printf(“src wb=%d et width=%d et%d”,src_wb,bi.biWidth,bi.biHeight);
int dst_wb=((bi.biWidth*8+31)/32)*4;
int src_size=src_wb*高度;
int dst_尺寸=dst_wb*高度;
//为源和目标分配
uint8_t*src=malloc(src_尺寸);
uint8_t*dst=malloc(dst_尺寸);
//读取像素
fread(src,1,src_尺寸,鳍);
//制作灰度颜色表
uint8_t clr[1024]={0};
对于(int i=0;i<256;i++)
clr[i*4+0]=clr[i*4+1]=clr[i*4+2]=(uint8_t)i;
对于(int y=height-1;y>=0;y--)
{
对于(int x=0;x>3;//5位
uint8_t grn=(uint8_t)((pt1&0xE)5);//6位
uint8_t blu=(pt1&0x11);//5位
uint8_t gry=(uint8_t)(.33*红色+.34*绿色+.33*蓝色);
dst[y*dst_wb+x]=gry;//这将匹配颜色表中的索引
}
}
//修改位图标题
bf.bfSize=54+1024+dst_尺寸;
bf.bfOffBits=54+1024;
bibibitcount=8;
bi.biSizeImage=dst_尺寸;
bi.BICLRUSE=256;
双压缩=0;
fwrite(&bf,bf的大小,1,fout);
fwrite(&bi,bi的大小,1,fout);
写入(clr,1024,fout);
fwrite(dst,1,dst_尺寸,fout);
免费(src);
免费(dst);
错误:
fclose(fout);
财务总监(财务);
返回0;
}