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

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

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

详细的代码例如以下:

#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);
}

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

BMP的图像处理的更多相关文章

  1. c语言数字图像处理(一):bmp图片格式及灰度图片转换

    本篇文章首先介绍了bmp图片格式,主要参考wiki上的内容,包括bmp文件的存储方式,对于一些常见的bmp文件格式都给了例子,并且对8位 16位RGB555 16位RGB565格式的bmp文件进行了简 ...

  2. 图像处理笔记(1): bmp文件结构处理与显示

    1.1图和调色板的概念 如今Windows(3.x以及95,98,NT)系列已经成为绝大多数用户使用的操作系统,它比DOS成功的一个重要因素是它可视化的漂亮界面.那么Windows是如何显示图象的呢? ...

  3. 用最简单的方式在C#中使用多线程加速耗时的图像处理算法的执行(多核机器)。

    图像处理中,有很多算法由于其内在的复杂性是天然的耗时大户,加之图像本身蕴涵的数据量比一般的对象就大,因此,针对这类算法,执行速度的提在很大程度上依赖于硬件的性能,现在流行的CPU都是至少2核的,稍微好 ...

  4. C#中使用FreeImage库加载Bmp、JPG、PNG、PCX、TGA、PSD等25种格式的图像(源码)。

    其实我一直都是喜欢自己去做图像格式的解码的(目前我自己解码的图像格式大概有15种),但是写本文主要原因是基于CSDN的这个帖子的: http://bbs.csdn.net/topics/3905104 ...

  5. VB.NET中图像处理的一些技巧以及其和C#图像处理的差距。

    早期的时候我使用的开发工具是VB6,VB6做图像处理的速度在我的软件Imageshop中有所体现,还是算可以的.目前,我已经改用C#来研究图像算法,C#中有指针,做图像处理起来效率确实要高不少.VB. ...

  6. 图像处理工具V1.0

    图像处理工具V1.0(仿彗星图片处理工具.VS2015安装界面)----个人无聊作品 以下是界面: 部分代码一.(摘自网络----加水印代码): public static void ImageWat ...

  7. HTML5图形图像处理技术研究

    摘要:图形图像处理平台大部分是传统的C/S架构的桌面应用程序,维护困难,共享性差,而B/S架构的Web程序具有易维护.易共享的优点.本文研究了基于HTML5的Web图形图像处理技术,用HTML5实现了 ...

  8. 图像处理中的matlab使用

    图像的矩阵表示 类和图像类型 虽然使用的是整数坐标, 但 MATLAB 中的像素值(亮度)并未限制为整数. 表 1-1 列出了 MATLAB 和图像处理工具箱为描述像素值而支持的各种类. 表中的前 8 ...

  9. 基于小波变换的数字图像处理(MATLAB源代码)

    基于小波变换的数字图像处理(MATLAB源代码) clear all; close all; clc;M=256;%原图像长度N=64; %水印长度[filename1,pathname]=uiget ...

随机推荐

  1. 附加数据库错误代码 - 950【MSSQL】

    分析 (539)代表的是Sql Server 2000数据库的内部版本号,也就是说要附加的数据库文件是由Sql Server 2000创建的,但是我们知道Sql Server 2016 数据库是不兼容 ...

  2. CF842C Ilya And The Tree

    思路: 1. 如果根节点是0,那么可以通过一次dfs计算出所有节点的最大值. 2. 如果根节点不是0,那么其余各点的最大值一定是根节点的一个因子.首先计算出根节点的所有因子.在dfs到一个深度为d的节 ...

  3. Hibernate+Spring整合开发步骤

    Hibernate是一款ORM关系映射框架+Spring是结合第三方插件的大杂烩,Hibernate+Spring整合开发效率大大提升. 整合开发步骤如下: 第一步:导入架包: 1.Hibernate ...

  4. Windows10环境中 laravel任务调度 如何启动调度

    Windows10环境中 laravel任务调度 如何启动调度 一:问题由来 1:今天在做用laravel开发订单系统的时候,需要使用定时任务来大批量提交订单,测试一下订单金额是否有误.发现larav ...

  5. DNN结构构建:NAS网络结构搜索和强化学习、迁移学习

    前言 谷歌推出的NASNet架构,用于大规模图像分类和识别.NASNet架构特点是由两个AutoML设计的Layer组成--Normal Layer and Reduction Layer,这样的效果 ...

  6. mysqlbinlog flashback 使用最佳实践

    mysqlbinlog限制 该软件利用binlog中记录了操作前的数据镜像和操作后的数据镜像.有如下限制 1)binlog_format=row 2)必须打开binlog 3)只支持insert.up ...

  7. MFC_2.10选项卡控件的封装

    选项卡控件的封装 1.新建默认MFC项目 2.添加资源Dialog,属性style改child,边框改none,添加类取名CMyDialog1: 同理,CMyDialog2: 3.类向导,添加MFC类 ...

  8. R语言学习 - 线图一步法

    首先把测试数据存储到文件中方便调用.数据矩阵存储在line_data.xls和line_data_melt.xls文件中 (直接拷贝到文件中也可以,这里这么操作只是为了随文章提供个测试文件,方便使用. ...

  9. CAD制作简单动画

    主要用到函数说明: IMxDrawEntity::Rotate 旋转一个对象.详细说明如下: 参数 说明 [in] IMxDrawPoint* basePoint 旋转基点 [in] DOUBLE d ...

  10. vue父子通信的基本使用

    项目中没怎么用过父子通信,很多页面都是路由切换实现的,后来做首页的时候发现首页的路径没法配置,我强行在原先的首页上写了个子组件,通过判断路径使其强行跳转实现的 这个时候跳转页面的时候就要使用到了父子间 ...