#include <iostream>
#include "stdio.h"
#include <math.h>
#include "Windows.h"
#define PI 3.14159265
//包含有关BITMAPFILEHEADER、BITMAPINFOHEADER、RGBQUAD等结构定义
using namespace std;
/******for moving*********/
unsigned char *pBmpBuf;//读入图像数据的指针
unsigned char *pBmpBuf1; //变换后图像数据指针
unsigned char *pTemp,*pTemp1; //临时指针
int width,height; //图像宽,高,实际大小,imgSize必须为4的倍数,bmp格式文件结构规定
int srcX[2],srcY[2],dstX[2],dstY[2]; //平移前后位置
int lineByte;
RGBQUAD *pColorTable;//颜色表指针
BITMAPFILEHEADER fileHead;
BITMAPINFOHEADER head;
/***********************************************************************
*函数名称:readBmp()
*函数参数:char *bmpName -文件名字及路径
*返回值:0为失败,1为成功
*说明: 给定一个图像文件名及其路径,读图像的位图数据、宽、高、颜色表及每像素
*位数等数据进内存,存放在相应的全局变量中
***********************************************************************/
bool readBmp(char *bmpName){
//二进制读方式打开指定的图像文件S
FILE *fp=fopen(bmpName,"rb");
if(fp==0) return 0;
fread(&fileHead,sizeof(BITMAPFILEHEADER),1,fp);
//将一个BITMAPINFOHEADER大小的byte读到head里
fread(&head, sizeof(BITMAPINFOHEADER), 1,fp);
//灰度图像有platte,且platte表项为256
//调色板(color table)是单色、16色和256色图像文件所特有的,
//相对应的调色板大小是2、16和256
//调色板以4字节为单位,每4个字节存放一个颜色值,图像 的数据是指向调色板的索引。
switch(head.biBitCount){
case 16:
case 24:
case 32:
break;
case 8:
//申请颜色表所需要的空间,读颜色表进内存
pColorTable=new RGBQUAD[256];
fread(pColorTable,sizeof(RGBQUAD),256,fp);
break;
case 4:
pColorTable=new RGBQUAD[16];
fread(pColorTable,sizeof(RGBQUAD),16,fp);
break;
case 1:
pColorTable=new RGBQUAD[2];
fread(pColorTable,sizeof(RGBQUAD),2,fp);
break;
}
//申请位图数据所需要的空间,读位图数据进内存
//lineByte 是向4round过的
//pBmpBuf=new unsigned char[lineByte * bmpHeight];
pBmpBuf=new unsigned char[head.biSizeImage];
//printf("%d,%d,%d",sizeof(pBmpBuf),biSizeImage,lineByte * bmpHeight);
fread(pBmpBuf,1,head.biSizeImage,fp);
//关闭文件
fclose(fp);
return 1;
}
/*****************************************
* 函数名称:saveBmp()
* 函数参数:
* char *bmpName-文件名字及路径
* unsigned char *imgBuf-待存盘的位图数据
*返回值:0为失败,1为成功
*
*说明:给定一个图像位图数据、宽、高、颜色表指针及每像素所占的位数等信息,
* 将其写到指定文件中
***********************************************************************/
bool saveBmp(char *bmpName)
{
FILE *fp = fopen(bmpName,"wb"); //以二进制写方式打开指定的图像文件
if(NULL == fp)
{
cout<<"file not exist!";
return 0;
}
//写入BMP文件数据
fwrite(&fileHead,sizeof(BITMAPFILEHEADER),1,fp);
fwrite(&head,sizeof(BITMAPINFOHEADER),1,fp);
//如果灰度图像,有颜色表,写入文件
switch(head.biBitCount){
case 16:
case 24:
case 32:
break;
case 8:
fwrite(pColorTable, sizeof(RGBQUAD),256, fp);
break;
case 4:
fwrite(pColorTable, sizeof(RGBQUAD),16, fp);
break;
case 1:
fwrite(pColorTable, sizeof(RGBQUAD),2, fp);
break;
}
fwrite(pBmpBuf1,sizeof(char),head.biSizeImage,fp);
fclose(fp);
return 1;
}
/**
* 函数名: rotate
* 参 数:
* 功 能: 实现旋转
*/
void rotate(char *bmpName, double angle){
int h_n,w_n;
int x0,y0,x1,y1;
double old[4][2];//四个顶点
int ne[4][2];
width = head.biWidth;
height = head.biHeight;
old[0][0]=0;
old[0][1]=0;
old[1][0]=width;
old[1][1]=0;
old[2][0]=0;
old[2][1]=height;
old[3][0]=width;
old[3][1]=height;
//printf("%lf\n",angle);
angle = angle*PI/180.0;
// printf("%lf\n",PI);
//printf("%lf\n",angle);
//angle = angle /180.0; printf("%f\n",angle);
for(int i=0;i<4;i++){
ne[i][0]=old[i][0]*cos(angle)-old[i][1]*sin(angle)-0.5*width*cos(angle)+0.5*height*sin(angle);
ne[i][1]=old[i][0]*(-sin(angle))-old[i][1]*cos(angle)+0.5*width*sin(angle)+0.5*height*cos(angle);
}
w_n = max(fabs(ne[3][0]-ne[0][0]),fabs(ne[2][0]-ne[1][0]))+1;
h_n = max(fabs(ne[3][1]-ne[0][1]),fabs(ne[2][1]-ne[1][1]))+1;
printf("%d,%d",w_n,h_n);
lineByte=(head.biWidth *head.biBitCount/8+3)/4*4;
int lineByte1=(w_n *head.biBitCount/8+3)/4*4;
unsigned char* pBmpBuf_r = new unsigned char[h_n*lineByte1];
memset(pBmpBuf_r,(char)255,h_n*lineByte1);
for(y1 = 0;y1< h_n ;y1++){
for(x1=0;x1<w_n;x1++){
x0=int(x1*cos(angle)+y1*sin(angle)-0.5*w_n*cos(angle)-0.5*h_n*sin(angle)+0.5*width);
y0=int(x1*(-sin(angle))+y1*cos(angle)+0.5*w_n*sin(angle)-0.5*h_n*cos(angle)+0.5*height);
int x,y;
y = height -1 -y0;
x = x0;
if(y>=0&&y<=height&&x>=0&&x<=width){
pTemp = pBmpBuf + (height - 1 - y0)*lineByte + x0;
//pTemp1指向要拷贝的那一行的最左边的象素对应在新图中的位置。同样要注意上面的问题。
pTemp1 = pBmpBuf_r + (h_n - 1 - y1)*lineByte1 + x1;
*pTemp1 = *pTemp;
}
}
}
FILE *fp = fopen(bmpName,"wb"); //以二进制写方式打开指定的图像文件
if(NULL == fp)
{
cout<<"file not exist!";
return ;
}
//写入BMP文件数据
BITMAPFILEHEADER fileHead_n;
BITMAPINFOHEADER head_n;
fileHead_n=fileHead;
fileHead_n.bfSize= fileHead.bfOffBits+h_n*lineByte1;
head_n=head;
head_n.biWidth = w_n;
head_n.biHeight= h_n;
head_n.biSizeImage = h_n*lineByte1;
fwrite(&fileHead_n,sizeof(BITMAPFILEHEADER),1,fp);
fwrite(&head_n,sizeof(BITMAPINFOHEADER),1,fp);
switch(head.biBitCount){
case 16:
case 24:
case 32:
break;
case 8:
fwrite(pColorTable, sizeof(RGBQUAD),256, fp);
break;
case 4:
fwrite(pColorTable, sizeof(RGBQUAD),16, fp);
break;
case 1:
fwrite(pColorTable, sizeof(RGBQUAD),2, fp);
break;
}
fwrite(pBmpBuf_r,sizeof(char),h_n*lineByte1,fp);
fclose(fp);
}
/**
* 函数名: horizontal
* 参 数:
* 功 能: 实现水平镜像
*/
void horizontal(char *bmpName){
unsigned char* pBmpBuf_h = new unsigned char[head.biSizeImage];
memset(pBmpBuf_h,(char)255,head.biSizeImage);
int h_s,w_s;
width = head.biWidth;
height = head.biHeight;
lineByte=(head.biWidth*head.biBitCount/8+3)/4*4;
for(int h_d=0;h_d<height ;h_d++){
for(int w_d=0;w_d<width;w_d++){
w_s=width-1-w_d;
h_s=h_d;
pTemp = pBmpBuf + (height - 1 - h_s)*lineByte + w_s;
//pTemp1指向要拷贝的那一行的最左边的象素对应在新图中的位置。同样要注意上面的问题。
pTemp1 = pBmpBuf_h + (height - 1 - h_d)*lineByte + w_d;
*pTemp1 = *pTemp;
}
}
pBmpBuf1 = pBmpBuf_h;
saveBmp(bmpName);
}
/**
* 函数名: vertical
* 参 数:
* 功 能: 实现垂直镜像
*/
void vertical(char *bmpName){
unsigned char* pBmpBuf_v = new unsigned char[head.biSizeImage];
memset(pBmpBuf_v,(char)255,head.biSizeImage);
int h_s,w_s;
width = head.biWidth;
height = head.biHeight;
lineByte=(head.biWidth *head.biBitCount/8+3)/4*4;
for(i
BMP文件旋转,平移,镜像,缩放
5星 · 超过95%的资源 需积分: 19 18 浏览量
2013-05-22
21:39:52
上传
评论 1
收藏 337KB ZIP 举报
suncyqq
- 粉丝: 0
- 资源: 6
最新资源
- 基于Vue+Echarts实现风力发电机中传感器的数据展示监控可视化系统+源代码+文档说明(高分课程设计)
- 基于单片机的风力发电机转速控制源码
- 基于C++实现的风力发电气动平衡监测系统+源代码+测量数据(高分课程设计)
- 毕业设计- 基于STM32F103C8T6 单片机,物联网技术的太阳能发电装置+源代码+文档说明+架构图+界面截图
- 基于 LSTM(长短期记忆)(即改进的循环神经网络)预测风力发电厂中风力涡轮机产生的功率+源代码+文档说明
- 基于stm32f103+空心杯电机+oled按键+运动算法
- 《CKA/CKAD应试指南/从docker到kubernetes 完全攻略》学习笔记 第1章docker基础(1.1-1.4)
- 基于python实现的水下压缩空气储能互补系统建模仿真与经济效益分析+源代码+论文
- 华中科技大学-自然语言处理实验,Bi-LSTM+CRF的中文分词框架,并且利用基于深度学习的方法进行中文命名实体识别++源码报告
- 基于动态罚函数的铁路车流分配与径路优化模型python源码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈