zoukankan      html  css  js  c++  java
  • 镜像, 转置, 锐化, 灰度,旋转

    /** 
    * 函数名: mirror 
    * 功  能: 对图片进行水平和垂直镜像操作 
    */  
    void mirror()  
    {  
        int height = bmpInfoHeader.biHeight;  
        int width = bmpInfoHeader.biWidth;  
        int imgSize = bmpInfoHeader.biSizeImage;  
        memset(pXBmpData,0,sizeof(unsigned char )*imgSize);  
        memset(pYBmpData,0,sizeof(unsigned char )*imgSize);  
        int lineByte = (width * 8 + 31) / 32 * 4;  //每行像素的字节数  
        for(int i = 0; i < height; i++ )  
        {  
            for(int j = 0; j < width; j++ )  
            {  
                *(pXBmpData + i*lineByte + width - 1 - j) = *(pBmpData + i*lineByte + j); //水平镜像  
                *(pYBmpData + (height - i - 1)*lineByte + j) = *(pBmpData + i*lineByte + j);  //垂直镜像  
            }  
        }  
    }  
    /** 
    * 函数名: transpose
    * 功 能: 对图像进行转置处理 */

    void transpose() { int height = bmpInfoHeader.biHeight; int width = bmpInfoHeader.biWidth; int imgSize = bmpInfoHeader.biSizeImage; //转置之后高宽变了 bmpInfoHeader.biHeight = width; bmpInfoHeader.biWidth = height; memset(pNewBmpData,0,sizeof(unsigned char )*imgSize); int lineByte = (width * 8 + 31) / 32 * 4; //每行像素的字节数 int newLineByte = (height * 8 + 31) / 32 * 4; //新的lineByte for(int i = 0; i < height; i++ ) { for(int j = 0; j < width; j++ ) { *(pNewBmpData + (width - 1 - j)*newLineByte + i) = *(pBmpData + (height - 1 - i)*lineByte + j); //转置 } } }
        /** 
        * 函数名: sharpening 
        * 功  能: 对图像进行锐化处理 
        */  
        void Laplacian()  
        {  
            int temp[9] = {-1,-1,-1,-1,9,-1,-1,-1,-1};   //Laplacian 模版  
            int height = bmpInfoHeader.biHeight;     
            int width = bmpInfoHeader.biWidth;    
            int imgSize = bmpInfoHeader.biSizeImage;  
            int lineByte = (width * 8 +31) / 32 * 4;  //每行像素所占字节数  
            //处理是基于原图的,所以原图的数据不能改变,用pNewBmpData存储改变之后的数据  
            memcpy(pNewBmpData,pBmpData,imgSize);   //把原图数据复制给pNewBmpData  
            //注意边界点不处理,所以i从1到高度-2,j类似  
            double temResult;  //中间结果  
            for(int i = 1; i < height - 1; i++ )  
            {  
                for(int j = 1; j < width - 1; j++ )  
                {  
                    temResult = (double)(*(pBmpData + (i-1) * lineByte + j - 1) * temp[0]);  
                    temResult += (double)(*(pBmpData + (i-1) * lineByte + j) * temp[1]);  
                    temResult += (double)(*(pBmpData + (i-1) * lineByte + j + 1) * temp[2]);  
                    temResult += (double)(*(pBmpData + (i) * lineByte + j - 1) * temp[3]);  
                    temResult += (double)(*(pBmpData + (i) * lineByte + j) * temp[4]);  
                    temResult += (double)(*(pBmpData + (i) * lineByte + j + 1) * temp[5]);  
                    temResult += (double)(*(pBmpData + (i+1) * lineByte + j - 1) * temp[6]);  
                    temResult += (double)(*(pBmpData + (i+1) * lineByte + j) * temp[7]);  
                    temResult += (double)(*(pBmpData + (i+1) * lineByte + j + 1) * temp[8]);  
                    *(pNewBmpData + i * lineByte + j) = temResult;  
                }  
            }  
        }  


    /** 
    * 程序名: Rotation.cpp 
    * 功  能: 实现灰度图像的旋转,如果超出原图范围,则用白色填充 
    *         测试位图为test.bmp放到工程目录下 
    */  
    #include <iostream>  
    #include <fstream>  
    #include <cstring>  
    #include <cmath>  
    #include <windows.h>  
    using namespace std;  
    #define PI 3.1415926535  
    #define RADIAN(angle) (((angle)*PI)/180.0)  
    BITMAPFILEHEADER bmpFileHeader;   //bmp文件头  
    BITMAPINFOHEADER bmpInfoHeader;   //bmp信息头  
    RGBQUAD *pColorTable;            //bmp颜色表     
    unsigned char *pBmpData;        //bmp位图数据  
    unsigned char *pNewBmpData;   //旋转后bmp位图数据  
    int newImgSize;         //旋转后图像大小  
      
    /** 
    * 函数名: readBmp 
    * 参  数: fileName--要读取文件的文件名 
    * 功  能: 读取bmp位图数据,成功返回TRUE,否则返回FALSE 
    */  
    BOOL readBmp(char *fileName)  
    {  
        FILE *fp = fopen(fileName,"rb");   //以二进制读方式打开  
        if (NULL == fp)  
        {  
            cout<<"The file is opened failure!"<<endl;  
            return FALSE;  
        }  
        //读取信息到相应的变量中  
        fread(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);  
        fread(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,fp);  
        pColorTable = new RGBQUAD[256];  
        fread(pColorTable,sizeof(RGBQUAD),256,fp);  
        int imgSize = bmpInfoHeader.biSizeImage;     //文图数据的大小,4的倍数  
        pBmpData = new  unsigned char[imgSize];  
        fread(pBmpData,sizeof(unsigned char),imgSize,fp);  
        fclose(fp);  
        return TRUE;  
    }  
    /** 
    * 函数名: rotation 
    * 参  数: rotAngle--要转换的角度 
    * 功  能: 实现bmp图像的旋转 
    */  
    void rotation(int rotAngle)  
    {  
        double cosa,sina,srcX[4],srcY[4],dstX[4],dstY[4],rad;  
        int oldWidth,oldHeight,newWidth,newHeight;  
        rad = (double)RADIAN(rotAngle);  
        cosa = cos(rad);  
        sina = sin(rad);  
        //原图宽与高  
        oldWidth = bmpInfoHeader.biWidth;  
        oldHeight = bmpInfoHeader.biHeight;  
        //原图四个角的坐标  
        srcX[0] = -0.5 * oldWidth;  
        srcY[0] = 0.5 * oldHeight;  
        srcX[1] = 0.5 * oldWidth;  
        srcY[1] = 0.5 * oldHeight;  
        srcX[2] = 0.5 * oldWidth;  
        srcY[2] = -0.5 * oldHeight;  
        srcX[3] = -0.5 * oldWidth;  
        srcY[3] = -0.5 * oldHeight;  
        //新图四个角坐标  
        for(int i = 0; i < 4; i++ )  
        {  
            dstX[i] = cosa * srcX[i] + sina * srcY[i];  
            dstY[i] = -sina * srcX[i] + cosa * srcY[i];  
    //      cout<<dstY[i]<<endl;  
        }  
        //新图的宽与高,向上取整  
        bmpInfoHeader.biWidth = newWidth = (int)(max(fabs(dstX[0] - dstX[2]),fabs(dstX[1] - dstX[3])) + 0.5);  
        bmpInfoHeader.biHeight = newHeight = (int)(max(fabs(dstY[0] - dstY[2]),fabs(dstY[1] - dstY[3])) + 0.5);  
    //  cout<<newWidth<<newHeight<<endl;  
        //新图位图数据大小  
        bmpInfoHeader.biSizeImage = newImgSize = newHeight * ((newWidth * bmpInfoHeader.biBitCount + 31) / 32 * 4);  
        pNewBmpData = new unsigned char[newImgSize];  
        double temp1,temp2;   //计算矩阵(2.9)中的两个常数,这样不用以后每次都计算了  
        temp1 = -0.5 * newWidth * cosa - 0.5 * newHeight * sina + 0.5 * oldWidth;  
        temp2 = 0.5 * newWidth * sina - 0.5 * newHeight * cosa + 0.5 * oldHeight;  
        memset(pNewBmpData,(BYTE)255,newImgSize);   //先全部填充成白色  
        int x0,y0,x1,y1;  
        unsigned char *pOldTemp,*pNewTemp;  
        int oldLineByte,newLineByte;  
        oldLineByte = (oldWidth * bmpInfoHeader.biBitCount + 31) / 32 * 4;  
        newLineByte = (newWidth * bmpInfoHeader.biBitCount + 31) / 32 * 4;  
        //把旋转后的图像数据对应存储到pNewBmpData相应位置  
        for(y1 = 0; y1 < newHeight; y1++)  
        {  
            for(x1 = 0; x1 < newWidth; x1++ )  
            {  
                x0 = (int)(x1 * cosa + y1 * sina + temp1);  
                y0 = (int)(-x1 * sina + y1 * cosa + temp2);  
                if((x0 >= 0 && x0 < oldWidth) && (y0 >= 0 && y0 < oldHeight))    //这里不能为<=oldWidth或oldHeight  
                {  
                    pOldTemp = pBmpData + (oldHeight - 1 - y0) * oldLineByte + x0;  
                    pNewTemp = pNewBmpData + (newHeight - 1 - y1) * newLineByte + x1;  
                    *pNewTemp = *pOldTemp;  
                }  
            }  
        }  
    }  
    /** 
    * 函数名: writeBmp 
    * 参  数: bmpName -- 旋转后的bmp文件名 
    * 功  能: 新建一个bmp文件,把旋转后的图像信息存入其中 
    */  
    void writeBmp(char *bmpName)  
    {  
        FILE *fp = fopen(bmpName,"wb");  //以二进制写方式打开  
        if(NULL == fp)  
            cout<<"The file is opened failure"<<endl;  
        //写入选装后图像信息  
        fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);  
        fwrite(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,fp);  
        fwrite(pColorTable,sizeof(RGBQUAD),256,fp);  
        fwrite(pNewBmpData,sizeof(unsigned char),newImgSize,fp);  
        fclose(fp);  
            delete []pColorTable;  
            delete []pNewBmpData;  
            delete []pBmpData;  
     }  
    /** 
    * 函数名: work 
    * 参  数: 无 
    * 功  能: 实现处理工作 
    */  
    void work()  
    {  
        char readBmpName[] = "test.bmp";  
        if ( !readBmp(readBmpName))  
            cout<<"The file "<<readBmpName<<"is read failure"<<endl;  
        cout<<"please input the angle to rotate(Clockwise):";  
        int rotAngle;  
        cin>>rotAngle;  
        rotation(rotAngle);  
        char writeBmpName[] = "test_new.bmp";  
        writeBmp(writeBmpName);  
    }  
    int main()  
    {  
        work();  
        return 0;  
    }  
  • 相关阅读:
    mysql数据库全局只读和会话只读问题解析
    git仓库管理笔录
    使用 keytool 生成安卓应用程序签名
    html标签种类很多,为什么不都用div?
    css不受高度限制实现文本超出隐藏并以省略号结束
    进程、单线程、多线程
    CentOS7防火墙firewalld设置
    js 浏览器上调试方法多样
    javascript中call()、apply()、bind()的用法终于理解
    将图标LOGO之类的图形图像转换成字体调用方法大全
  • 原文地址:https://www.cnblogs.com/chencesc/p/5749545.html
Copyright © 2011-2022 走看看