BMP的图像处理
近期碰到了一个问题将图片缩放:
进行了整理发现位图一些主要的结构能够进行整理,得出下面图表:
进行图片缩放的时候会进行一些处理(最临近差值法):
详细的代码例如以下:
#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的图像处理的更多相关文章
- c语言数字图像处理(一):bmp图片格式及灰度图片转换
本篇文章首先介绍了bmp图片格式,主要参考wiki上的内容,包括bmp文件的存储方式,对于一些常见的bmp文件格式都给了例子,并且对8位 16位RGB555 16位RGB565格式的bmp文件进行了简 ...
- 图像处理笔记(1): bmp文件结构处理与显示
1.1图和调色板的概念 如今Windows(3.x以及95,98,NT)系列已经成为绝大多数用户使用的操作系统,它比DOS成功的一个重要因素是它可视化的漂亮界面.那么Windows是如何显示图象的呢? ...
- 用最简单的方式在C#中使用多线程加速耗时的图像处理算法的执行(多核机器)。
图像处理中,有很多算法由于其内在的复杂性是天然的耗时大户,加之图像本身蕴涵的数据量比一般的对象就大,因此,针对这类算法,执行速度的提在很大程度上依赖于硬件的性能,现在流行的CPU都是至少2核的,稍微好 ...
- C#中使用FreeImage库加载Bmp、JPG、PNG、PCX、TGA、PSD等25种格式的图像(源码)。
其实我一直都是喜欢自己去做图像格式的解码的(目前我自己解码的图像格式大概有15种),但是写本文主要原因是基于CSDN的这个帖子的: http://bbs.csdn.net/topics/3905104 ...
- VB.NET中图像处理的一些技巧以及其和C#图像处理的差距。
早期的时候我使用的开发工具是VB6,VB6做图像处理的速度在我的软件Imageshop中有所体现,还是算可以的.目前,我已经改用C#来研究图像算法,C#中有指针,做图像处理起来效率确实要高不少.VB. ...
- 图像处理工具V1.0
图像处理工具V1.0(仿彗星图片处理工具.VS2015安装界面)----个人无聊作品 以下是界面: 部分代码一.(摘自网络----加水印代码): public static void ImageWat ...
- HTML5图形图像处理技术研究
摘要:图形图像处理平台大部分是传统的C/S架构的桌面应用程序,维护困难,共享性差,而B/S架构的Web程序具有易维护.易共享的优点.本文研究了基于HTML5的Web图形图像处理技术,用HTML5实现了 ...
- 图像处理中的matlab使用
图像的矩阵表示 类和图像类型 虽然使用的是整数坐标, 但 MATLAB 中的像素值(亮度)并未限制为整数. 表 1-1 列出了 MATLAB 和图像处理工具箱为描述像素值而支持的各种类. 表中的前 8 ...
- 基于小波变换的数字图像处理(MATLAB源代码)
基于小波变换的数字图像处理(MATLAB源代码) clear all; close all; clc;M=256;%原图像长度N=64; %水印长度[filename1,pathname]=uiget ...
随机推荐
- spring-redis-data的一个坑
事故原因: 运维报告redis内存直线上升,然后查询发现都是setrange操作,review代码,没法发现setrange操作 代码如下: redisTemplate.opsForValue().s ...
- 选择语言之switch case
程序语言-选择语言之switch case 多选一,类似if else if else if else 模版: Switch(选择条件) { Case(条件一)//相当于if Conso ...
- 两个input可能会用到的小方法
1.一个普通的input元素,在不被 form包裹的时候,如何跳转或搜索 var oInput = document.getElementsByTagName('input')[0]; oInput. ...
- 联想 Z5(L78011) 免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 10.5.254
>>>重点介绍<<< 第一:本刷机包可卡刷可线刷,刷机包比较大的原因是采用同时兼容卡刷和线刷的格式,所以比较大第二:[卡刷方法]卡刷不要解压刷机包,直接传入手机后用 ...
- JDBC更新10W级以上数据性能优化
随笔缘由: 系统完成到一定程度,少不了要往数据库中添加大量数据进行性能测试. 我用程序做数据10W条,使用jdbc批更新的API,发现每次只能插入2W多条记录. 一番小小研究,觉得总结一下可能有些意义 ...
- Zynq7000系列之芯片引脚功能综述
很多人做了很久的FPGA,知道怎么去给信号分配引脚,却对这些引脚的功能及其资源限制知之甚少:在第一章里对Zynq7000系列的系统框架进行了分析和论述,对Zynq7000系列的基本资源和概念有了大致的 ...
- python学习笔记(4)——list[ ]
发现个问题,python与C.JAVA等语言相比学习障碍最大差别居然在于版本更迭!这是python官方造的虐啊... 有时针对某问题去google答案,或者自己去博客找共性解答,会出现相互矛盾或者与你 ...
- 再谈布局之 UIStackView
UIStackView 是 iOS9 新增的一个布局技术.熟练掌握相当节省布局时间. UIStackView 是 UIView 的子类,是用来约束子控件的一个控件.但他的作用仅限于此,他不能被渲染(即 ...
- 简单工厂模式&工厂方法模式&抽象工厂模式的区别
之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略.这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个 ...
- datagrid总条数
1.getData var data=$("#dg").datagrid("getData");alert('总数据量:' + data.total)//注意你 ...