将一个bmp图片缩小为原来的二分之一
本文最后更新于 163 天前,其中的信息可能已经有所发展或是发生改变。
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#pragma pack(push, 1)
typedef struct
{
    uint16_t bfType;
    uint32_t bfSize;
    uint16_t bfReserved1;
    uint16_t bfReserved2;
    uint32_t bfOffBits;
} BITMAPFILEHEADER;

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

int main(int argc, const char *argv[])
{
    if (argc != 3)
    {
        printf("用法: %s <输入BMP> <输出BMP>\n", argv[0]);
        return -1;
    }

    FILE *in = fopen(argv[1], "rb");
    if (!in)
    {
        perror("打开输入文件失败");
        return -1;
    }

    BITMAPFILEHEADER fh;
    BITMAPINFOHEADER ih;
    fread(&fh, 1, sizeof(fh), in);
    fread(&ih, 1, sizeof(ih), in);

    // 仅处理 24 位无压缩 BMP
    if (ih.biBitCount != 24 || ih.biCompression != 0)
    {
        printf("仅支持 24 位未压缩 BMP\n");
        fclose(in);
        return -1;
    }

    int old_width = ih.biWidth;
    int old_height = ih.biHeight;
    int old_bitcount = ih.biBitCount;

  // ... 前面的代码不变 (直到计算出 old_row_size) ...

    int old_row_size = ((old_width * old_bitcount + 31) / 32) * 4;
    int old_pixel_size = old_row_size * old_height; // 原图数据总大小

    // 1. 【新增】把原图完整读到内存中
    unsigned char *old_pixels = (unsigned char *)malloc(old_pixel_size);
    if (!old_pixels) {
        perror("原图内存分配失败");
        return -1;
    }
    fseek(in, fh.bfOffBits, SEEK_SET);
    fread(old_pixels, 1, old_pixel_size, in);

    // 新图像尺寸计算 (你的代码)
    int new_width = old_width / 2;
    int new_height = old_height / 2;
    int new_row_size = ((new_width * 24 + 31) / 32) * 4;
    int new_pixel_size = new_row_size * new_height;

    // 分配新像素缓冲区 (你的代码)
    unsigned char *new_pixels = (unsigned char *)calloc(new_pixel_size, 1);
    if (!new_pixels) {
        perror("内存分配失败");
        return -1;
    }

    // 2. 【核心修改】二维坐标映射 (最近邻插值法缩放)
    // 遍历新图的每一个像素点
    for (int y = 0; y < new_height; y++) 
    {
        for (int x = 0; x < new_width; x++) 
        {
            // 计算当前新像素在 new_pixels 数组里的起始位置
            // 公式:当前行数 * 新行宽 + 当前列数 * 3
            int new_index = y * new_row_size + x * 3;

            // 计算这个点对应在原图中的位置
            // 因为缩小了2倍,所以去原图里找 (x*2, y*2) 这个坐标的像素
            int old_x = x * 2;
            int old_y = y * 2;
            int old_index = old_y * old_row_size + old_x * 3;

            // 把原图的 B, G, R 复制到新图
            new_pixels[new_index]     = old_pixels[old_index];     // B
            new_pixels[new_index + 1] = old_pixels[old_index + 1]; // G
            new_pixels[new_index + 2] = old_pixels[old_index + 2]; // R
        }
    }

    // ... 后面构建 new_fh, new_ih 并写入文件的代码不变 ...
    
    // 记得最后释放新分配的 old_pixels
    free(old_pixels);



    // 构建新文件头和信息头
    BITMAPFILEHEADER new_fh;
    BITMAPINFOHEADER new_ih;

    new_fh.bfType = 0x4D42;
    new_fh.bfSize = sizeof(new_fh) + sizeof(new_ih) + new_pixel_size;
    new_fh.bfReserved1 = 0;
    new_fh.bfReserved2 = 0;
    new_fh.bfOffBits = sizeof(new_fh) + sizeof(new_ih);

    new_ih.biSize = sizeof(new_ih);
    new_ih.biWidth = new_width;
    new_ih.biHeight = new_height; // 保持与原图相同的符号(正数)
    new_ih.biPlanes = 1;
    new_ih.biBitCount = 24;
    new_ih.biCompression = 0;
    new_ih.biSizeImage = new_pixel_size;
    new_ih.biXPelsPerMeter = ih.biXPelsPerMeter; // 保持原分辨率或填默认值
    new_ih.biYPelsPerMeter = ih.biYPelsPerMeter;
    new_ih.biClrUsed = 0;
    new_ih.biClrImportant = 0;

    FILE *out = fopen(argv[2], "wb");
    if (!out)
    {
        perror("创建输出文件失败");
        free(new_pixels);
        return -1;
    }

    fwrite(&new_fh, 1, sizeof(new_fh), out);
    fwrite(&new_ih, 1, sizeof(new_ih), out);
    fwrite(new_pixels, 1, new_pixel_size, out);

    fclose(out);
    free(new_pixels);

    printf("缩小一半的图像已生成: %s\n", argv[2]);
    return 0;
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇