图像平移(translation)运算和镜像(mirror)运算

来源:互联网 发布:知乎win10显示不了桌面 编辑:程序博客网 时间:2024/06/08 20:08


还是以24位BMP图像为例,图像的平移和镜像运算都较为简单,只需要注意几点:

1、BMP图像像素宽度必须被4整除,因此如果平移后的像素宽度也必须对齐

2、BMP图像是倒着存放的,在平移的时候要得想明白坐标系朝向


顺便说句,之前几篇blog里面的代码我都要求输入图像input.bmp的像素宽度必须能被4整除,然后我觉得这么偷懒也不是办法 = =。所以还是加了一些判定来解决这个问题。所以接下来的代码中都不要求输入图像的像素宽度是对齐的了。

另外在这个网站在线转换出来的bmp图片都能用下面的代码进行运算: http://pic.55.la

而用PS转换的bmp图片有时候会多出两个像素点导致我的程序无法识别 = =。目前还不知道是为什么

代码如下:

#include <cstdio>#include <iostream>#include <vector>#include <algorithm>#include <cmath>#include <cstdlib>using namespace std;#define TRANSLATION_X 200#define TRANSLATION_Y 200typedef unsigned char BYTE;typedef unsigned short WORD;typedef unsigned int DWORD;//位图文件头定义;typedef struct  tagBITMAPFILEHEADER{//WORD bfType;//单独读取,结构体中就不定义了DWORD bfSize;//文件大小WORD bfReserved1;//保留字WORD bfReserved2;//保留字DWORD bfOffBits;//从文件头到实际位图数据的偏移字节数}BITMAPFILEHEADER;typedef struct tagBITMAPINFOHEADER{DWORD biSize;//信息头大小DWORD biWidth;//图像宽度DWORD biHeight;//图像高度WORD biPlanes;//位平面数,必须为1WORD biBitCount;//每像素位数DWORD  biCompression; //压缩类型DWORD  biSizeImage; //压缩图像大小字节数DWORD  biXPelsPerMeter; //水平分辨率DWORD  biYPelsPerMeter; //垂直分辨率DWORD  biClrUsed; //位图实际用到的色彩数DWORD  biClrImportant; //本位图中重要的色彩数}BITMAPINFOHEADER; //位图信息头定义//像素信息typedef struct tagIMAGEDATA{BYTE blue;BYTE green;BYTE red;}DATA;BITMAPFILEHEADER strHead;BITMAPINFOHEADER strInfo;int h,w,size;int mW,mSize;WORD bfType;void translation(const DATA* src);void mirror(const DATA* src);void printImage(const DATA* src, string filename, int size);int main(){FILE *fpi;fpi=fopen("input.bmp","rb");if(fpi != NULL){//先读取文件类型fread(&bfType,1,sizeof(WORD),fpi);if(0x4d42!=bfType) {cout<<"Error: The file is not a bmp image!"<<endl;return 0;}//读取bmp文件的文件头和信息头fread(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpi);fread(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpi);       h=strInfo.biHeight;       w=strInfo.biWidth;       if(w % 4 == 0)       mW = w;       else       mW = (w/4+1)*4;       if(h*mW*3!=strInfo.biSizeImage){       cout<<"Error: image broken!"<<endl;       return 0;       }       size=strInfo.biSizeImage/3;        DATA *imgdata=new DATA[size];fread(imgdata,1,sizeof(DATA)*size,fpi);//读取bmp数据信息fclose(fpi);translation(imgdata);//perform the translationmirror(imgdata);// small(imgdata, 0.5);// large(imgdata, 0.5);}elsecout<<"Can't open the input file!"<<endl;return 0;}/*translate the image to the north-east position*/void translation(const DATA* src){int moveX, moveY;if(TRANSLATION_X % 4 == 0)moveX = TRANSLATION_X;elsemoveX = TRANSLATION_X/4*4;moveY = TRANSLATION_Y;int newH = h + moveY;int newW = mW + moveX;int newSize = newH * newW;DATA* target = new DATA[newSize];memset(target, 0, sizeof(DATA)*newSize);for (int i = 0; i < newH; i++){for (int j = 0; j < newW; j++){if(i < moveY){target[i*newW + j].red = 255;target[i*newW + j].blue = 255;target[i*newW + j].green = 255;continue;}if(j < moveX){target[i*newW + j].red = 255;target[i*newW + j].blue = 255;target[i*newW + j].green = 255;}else{target[i*newW + j] = src[(i- moveY)*mW + (j - moveX)];}}}FILE *fpo1;fpo1=fopen("translation.bmp","wb");BITMAPFILEHEADER newHead = strHead;BITMAPINFOHEADER newInfo = strInfo;newHead.bfSize = (DWORD)(newHead.bfSize - size*3 + newSize*3);newInfo.biHeight = (DWORD)newH;newInfo.biWidth = (DWORD)newW;newInfo.biSizeImage = (DWORD)(newSize * 3);fwrite(&bfType,1,sizeof(WORD),fpo1);fwrite(&newHead,1,sizeof(tagBITMAPFILEHEADER),fpo1);fwrite(&newInfo,1,sizeof(tagBITMAPINFOHEADER),fpo1);fwrite(target,1,sizeof(DATA)*(newSize),fpo1);fclose(fpo1);}void mirror(const DATA* src){DATA* target = new DATA[size];memset(target, 0, sizeof(DATA) * size);for (int i = 0; i < h; i++){for (int j = 0; j < mW; j++){target[i*mW + j] = src[i*mW + mW - 1 - j];}}FILE *fpo1;fpo1=fopen("mirror.bmp","wb");fwrite(&bfType,1,sizeof(WORD),fpo1);fwrite(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpo1);fwrite(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpo1);fwrite(target,1,sizeof(DATA)*(size),fpo1);fclose(fpo1);}


0 0
原创粉丝点击