将一个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
© 版权声明
本站所有资源来自于网络,仅供学习与参考,请勿用于商业用途,否则产生的一切后果将由您(转载者)自己承担!
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
THE END
暂无评论内容