文件IO-图像缩小

将一个bmp图像进行缩小,缩小后的图像不失真

/********************************************************************************
*
*
* 设计图片等比例不失真缩小的接口
* author:jindouliu2024@163.com 
* date:2025.4.19
* 
*
* Copyright (c)  2024-2025   jindouliu2024@163.com   All right Reserved
* ****************************************************************************/

/********************************************************************************************************
*
*
* 设计图片等比例不失真缩小的接口
* author:jindouliu2024@163.com 
* date:2025.4.19
* 
*
* Copyright (c)  2024-2025   jindouliu2024@163.com   All right Reserved
* ******************************************************************************************************/

#include <fcntl.h> 
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<sys/ioctl.h>
#include <unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdbool.h>
#include <sys/mman.h>
#pragma pack(1)
typedef struct tagBITMAP_FILE_HEADER
{
        short        bfType;//文件标识
        int          bfSize;//文件大小
        short        bfReserved1;//保留字
        short        bfReserved2;//保留字
        int          bfOffBits;//文件指示器偏移量相较于文件开头
} bpFile_Header, *PbpFile_Header;
typedef struct tagBITMAPINFOHEADER
{
        int          bpSize;//图像描述信息块的大小
        int          bpWidth;//图像宽度
        int          bpHeight;//图像高度
        short        bpPlanes;//图像的plane总数(恒为1)
        short        bpBitCount;//记录颜色的位数取值1(双色),4,6,24,32
        int          bpCompression;//数据压缩方式(0:不压缩;1:8位压缩;2:4位压缩)
        int          bpSizeImage;//图像区数据的大小,必须是4的倍数
        int          bpXPelsPerMeter;//水平每米有多少像素,在设备无关位图中,填写00H
        int          bpYPelsPerMeter;//垂直每米有多少像素,在设备无关位图中,填写00H
        int          bpClrUsed;// 此图像所有的颜色数,不用,固定为0
        int          bpClrImportant;// 重要颜色数,不用,固定为0
} bpINFO_HEADER, *PbpINFO_HEADER;
#pragma pack()

bool Shrink_Picture(char *src_picture,char *dest_picture,int sk_cnt)
{
        bpFile_Header src_fheader;
        bpINFO_HEADER src_header;
        int src_cnt = 0,dest_cnt = 0,cnt=0;
        
        //打开原图像
        FILE *src_fp = fopen(src_picture,"rb");
        if(src_fp == NULL){
            printf("open src_picture failed\n ");
            return false;
        }
        //打开目的图像
        FILE *dest_fp = fopen(dest_picture,"wb+");
        if(dest_fp == NULL){
            printf("open dest_picture failed\n ");
            return false;
        }
        bpFile_Header dest_fheader;
        bpINFO_HEADER dest_header;
        //获取原图像信息
       // fseek(src_fp,14,SEEK_SET);
        fread(&src_fheader,1,14,src_fp);
        fread(&src_header,1,40,src_fp);
        
        short data=0;
        //初步设置目标文件信息头信息
        dest_fheader = src_fheader;
        dest_header = src_header;
        //计算目标图像需要补齐的字节数目
        dest_cnt = ((4-(src_header.bpWidth/sk_cnt*24/8)%4)%4);
        //计算源图像补齐的字节数目
        src_cnt = ((4-(src_header.bpWidth*24/8)%4)%4);
        //定义存储数据的数组
        char info_buf[src_header.bpWidth*3],middata;
        printf("%d\n",src_cnt);
        printf("%d\n",src_header.bpWidth);
       
        printf("%d\n",src_header.bpHeight);
        //向目标文件写入文件信息
        fwrite(&src_fheader,14,1,dest_fp);
        fwrite(&src_header,40,1,dest_fp);
        fseek(dest_fp,0,SEEK_SET);
        fread(&dest_fheader,1,14,dest_fp);
        fread(&dest_header,1,40,dest_fp);
        //设置目标文件信息头信息
        dest_fheader.bfSize = (src_header.bpWidth/sk_cnt + dest_cnt)*src_header.bpHeight / sk_cnt;
        dest_header.bpWidth = src_header.bpWidth/sk_cnt;
        dest_header.bpHeight = src_header.bpHeight/sk_cnt;
        //dest_header.bpSizeImage = src_header.bpSizeImage/4;
        fseek(dest_fp,0,SEEK_SET);
        fwrite(&dest_fheader,1,14,dest_fp);
        fwrite(&dest_header,1,40,dest_fp);
        printf("%8ld",ftell(dest_fp));
        //fseek(src_fp,54,SEEK_SET);
        //逐行进行
        for(int heigth = 0; heigth <= src_header.bpHeight ;heigth +=sk_cnt){
            //按行读取原图像
            printf("%8ld",ftell(src_fp));
            fread(info_buf,1,src_header.bpWidth*3,src_fp);
            //printf("%8ld",ftell(src_fp));
            //将源图像的数据进行处理并放入目标图像
            for(int i=0;i<dest_header.bpWidth;i++){
                
                cnt++;
                fwrite(info_buf+i*3*sk_cnt,1,3,dest_fp);
               // printf("%8ld",ftell(src_fp));
                // fputc(info_buf[i],dest_fp);
                // fputc(info_buf[i+1],dest_fp);
                // fputc(info_buf[i+2],dest_fp);
            }

            //放入对齐字节
            for(int j=0;j<dest_cnt;j++){//dest_cnt+dest_header.bpWidth*3-cnt*3
               fputc('\0',dest_fp);  
            }
            cnt = 0;
           // printf("%4d",heigth);
            //设置源图像的偏移量
            fseek(src_fp,sk_cnt*src_cnt+src_header.bpWidth*3*(sk_cnt-1),SEEK_CUR);//fseek(src_fp,2*src_cnt+src_header.bpWidth*3,SEEK_CUR);
              
        }
        printf("%ld",ftell(src_fp));
        printf("%ld",src_fheader.bfSize);
        //关闭文件
        fclose(src_fp);
        fclose(dest_fp);
        return true;
}

int main(int argc,char*argv[])
{
    Shrink_Picture(argv[1],argv[2],4);
    return 0;

}

来源链接:https://www.cnblogs.com/lradian/p/18835368

© 版权声明
THE END
支持一下吧
点赞13 分享
评论 抢沙发
头像
请文明发言!
提交
头像

昵称

取消
昵称表情代码快捷回复

    暂无评论内容