近期碰到了一个问题将图片缩放:

进行了整理发现位图一些主要的结构能够进行整理,得出下面图表:

进行图片缩放的时候会进行一些处理(最临近差值法):

详细的代码例如以下:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <windows.h>
#include <stdlib.h> LONG IWidth; //原图像的宽
LONG IHeight; //原图像的高
LONG biBitCount; //每像素位数
LONG INewWidth; //新图像的宽
LONG INewHeight; //新图像的高
LONG ILineByte; //原图像数据每行的字节数
LONG INewLineByte; //新图像数据每行的字节数
float zoomnumber=1; //初始放大倍数赋值为1
unsigned char *pIBuf; //原图像像素指针
unsigned char *pINewBuf;//新图像像素指针 int ReadBmp(const char* bmpName)//以二进制方式读入指定的图像文件
{
FILE *fp=fopen(bmpName,"rb");
if(fp==0)
{
printf("打开文件失败\n");
return 0;
} fseek(fp,sizeof(BITMAPFILEHEADER),0);//跳过位图文件头
BITMAPINFOHEADER head;//定义位图信息头结构体变量。存放在变量head中
fread(&head,sizeof(BITMAPINFOHEADER),1,fp);//获取图像的高、宽和每像素所占的位数,接收地址head。单个元素大小文件头大小。元素个数1个,输入流fp
IWidth = head.biWidth;
IHeight = head.biHeight;
biBitCount = head.biBitCount;
ILineByte = (IWidth *biBitCount/8+3)/4*4;//计算原图像每行字节数,/4*4以保证是4的倍数
pIBuf = new unsigned char [ILineByte *IHeight];//定义一个矩阵用以存放原图像像素信息。pIBuf指向首地址
fread(pIBuf,1,ILineByte *IHeight,fp);//获取源文件像素信息。接收地址pIBuf,单个元素大小1字节,元素个数每行字节数*行数,输入流fp
return 1;//成功返回1
} int SaveBmp(const char* bmpName,unsigned char *imgBuf,int width,int height,int biBitCount)//图像存储
{
if(!imgBuf)//假设没有像素数据传入,则函数返回
return 0;
INewLineByte = (width * biBitCount/8+3)/4*4;//计算新图像每行字节数。/4*4以保证是4的倍数
FILE *fp = fopen(bmpName,"wb");//以二进制方式写文件
if(fp == 0)
return 0;
BITMAPFILEHEADER fileHead;//申请位图文件头结构变量,填写文件头信息
fileHead.bfType= 0x4d42;//bmp类型
fileHead.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ INewLineByte *height;//位图文件大小
fileHead.bfReserved1 = 0;//保留字
fileHead.bfReserved2 = 0;//保留字
fileHead.bfOffBits = 54;//文件头到实际的位图数据的偏移字节数。前三个部分字节数之和
fwrite(&fileHead,sizeof(BITMAPFILEHEADER),1,fp);//将新图像数据写入文件,获取数据地址fileHead,单个元素大小文件头大小,元素个数1个,输入流fp
BITMAPINFOHEADER head;//定义位图信息头结构变量,存放在变量head中
head.biBitCount = biBitCount;//24位
head.biClrImportant = 0;//位图显示过程中重要的颜色数,觉得全部的颜色都是重要的
head.biClrUsed = 0;//位图实际用到的颜色数为2的biBitCount次幂
head.biCompression = 0;//位图压缩类型
head.biHeight = height;//新图像高
head.biPlanes =1;//目标设备的级别
head.biSize = 40;//本结构体长度
head.biSizeImage = ILineByte *height;//实际的位图数据占用的字节数
head.biWidth = width;//新图像宽
head.biXPelsPerMeter = 0;//指定目标设备的水平分辨率
head.biYPelsPerMeter = 0;//指定目标设备的垂直分辨率
fwrite(&head,sizeof(BITMAPINFOHEADER),1,fp);//写入信息头
fwrite(imgBuf,height * INewLineByte,1,fp);//写入像素数据
fclose(fp);//关闭文件
return 1;
} int Zoom(const char* readPath )//图像缩放
{
char address[50];
ReadBmp(readPath);//读取图像
INewWidth = (int) ((IWidth * zoomnumber) +0.5);//新图像的宽度。此处加0.5是因为强制转换时不四舍五入,而是直接截去小数部分
INewHeight = (int) (IHeight * zoomnumber +0.5);//新图像的高带。此处加0.5是因为强制转换时不四舍五入,而是直接截去小数部分
ILineByte =(IWidth*biBitCount/8+3)/4*4;//原图像每行字节数
INewLineByte = (INewWidth * biBitCount/8+3)/4*4;//新图像每行字节数
pINewBuf = new unsigned char [INewLineByte * INewHeight];//定义一个矩阵用以存放新图像像素信息,pIBuf指向首地址 LONG i; //循环变量(像素在新图像中的坐标)
LONG j;
LONG k; //色彩选择,k=0时为蓝色,k=1时为绿色,k=2时为红色
LONG i0; //像素在原图像中的坐标
LONG j0; if(biBitCount == 24)
{
for(i = 0;i < INewHeight;i++)
{
for(j = 0; j < INewWidth;j++)
for(k=0;k<3;k++)
{
i0 = (int)(i/zoomnumber+0.5);
j0 = (int)(j/zoomnumber+0.5);
if((j0 >= 0) && (j0 < IWidth) && (i0 >=0)&& (i0 <IHeight))
{
*(pINewBuf+i*INewLineByte+j*3+k) = *(pIBuf+i0*ILineByte+j0*3+k);//最邻近插值
}
else
{
*(pINewBuf+i*INewLineByte+j*3+k)=255;
}
}
}
}
printf("输入bmp图像缩放后需保存的路径名称和后缀:");
gets(address);
SaveBmp(address,pINewBuf,INewWidth,INewHeight,biBitCount);//调用SaveBmp函数保存图像
delete []pINewBuf;//清除指针
return 1;
} void main()
{
char filepath[256];
printf("请输入bmp图片路径,名称和后缀:(如E:\1.bmp)");
scanf("%s",filepath);
ReadBmp(filepath);//调用ReadBmp函数
printf("请输入所要缩放的倍数(小于1为缩小,大于1为放大):");
scanf("%f",&zoomnumber);getchar();
Zoom(filepath);
}

验证下面图片效果还能够。

最新文章

  1. angularJS实践过程中出现的问题总结
  2. Redis为什么使用单进程单线程方式也这么快
  3. [ES] 安装
  4. jQuery实现手机竖直手风琴效果
  5. 设置一个顺手的Xcode
  6. loadrunner 功能详解(一) - Run-time Settings
  7. u-boot 之配置分析 (2)
  8. 欧拉工程第74题:Digit factorial chains
  9. 记一次SSH登陆失败问题的定位
  10. sql触发器知识
  11. iOS网络层架构设计分享
  12. Web工程软件升级之数据库升级(二)
  13. javaweb笔记之get和post的不同
  14. iOS 动画篇 (三) CADisplayLink与CoreGraphics实现动画
  15. jenkins log文件突然占满磁盘空间
  16. 第25月第11天 deeplearning.ai
  17. Codeforces 1144G Two Merged Sequences dp
  18. R - Dividing 多重背包
  19. JPA的配置文件
  20. git-fork其他人的代码

热门文章

  1. 关于java日期输出格式
  2. IDEA破解方法以及快捷键大全
  3. Scala-基础-函数(1)
  4. Unity笔记(3)自学第二天
  5. Farseer.net轻量级开源框架 入门篇:查询数据详解
  6. 【OpenCV】像素操作的数字图像处理
  7. 让元素div消失在视野中
  8. try catch影响Spring事务吗?
  9. fiddler培训
  10. 洛谷 4216 BZOJ 4448 [SCOI2015]情报传递