不问出处 發表於 2025-4-19 13:49:00

文件IO-图像缩小

<p>将一个bmp图像进行缩小,缩小后的图像不失真</p>
<pre><code>/********************************************************************************
*
*
* 设计图片等比例不失真缩小的接口
* author:jindouliu2024@163.com
* date:2025.4.19
*
*
* Copyright (c)2024-2025   jindouliu2024@163.com   All right Reserved
* ****************************************************************************/

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

#include &lt;fcntl.h&gt;
#include &lt;unistd.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include&lt;sys/ioctl.h&gt;
#include &lt;unistd.h&gt;
#include&lt;stdio.h&gt;
#include&lt;string.h&gt;
#include&lt;stdlib.h&gt;
#include&lt;stdbool.h&gt;
#include &lt;sys/mman.h&gt;
#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(&amp;src_fheader,1,14,src_fp);
      fread(&amp;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,middata;
      printf("%d\n",src_cnt);
      printf("%d\n",src_header.bpWidth);
      
      printf("%d\n",src_header.bpHeight);
      //向目标文件写入文件信息
      fwrite(&amp;src_fheader,14,1,dest_fp);
      fwrite(&amp;src_header,40,1,dest_fp);
      fseek(dest_fp,0,SEEK_SET);
      fread(&amp;dest_fheader,1,14,dest_fp);
      fread(&amp;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(&amp;dest_fheader,1,14,dest_fp);
      fwrite(&amp;dest_header,1,40,dest_fp);
      printf("%8ld",ftell(dest_fp));
      //fseek(src_fp,54,SEEK_SET);
      //逐行进行
      for(int heigth = 0; heigth &lt;= 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&lt;dest_header.bpWidth;i++){
               
                cnt++;
                fwrite(info_buf+i*3*sk_cnt,1,3,dest_fp);
               // printf("%8ld",ftell(src_fp));
                // fputc(info_buf,dest_fp);
                // fputc(info_buf,dest_fp);
                // fputc(info_buf,dest_fp);
            }

            //放入对齐字节
            for(int j=0;j&lt;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,argv,4);
    return 0;

}
</code></pre><br><br>
来源:https://www.cnblogs.com/lradian/p/18835368
頁: [1]
查看完整版本: 文件IO-图像缩小