zoukankan      html  css  js  c++  java
  • RotateZoom.cpp——Inter

    // RotateZoom.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include "RotateZoom.h"
    
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    #include <atlimage.h>
    #include <locale.h>
    
    // The one and only application object
    
    CWinApp theApp;
    
    using namespace std;
    //双三次插值系数
    double fs(double w)
    {    
            double a=-0.5;
            double fs;
            if (abs(w)<=1)
                fs=(a+2)*pow(abs(w),3)-(a+3)*pow(abs(w),2)+1;
            else if (abs(w)>1&&abs(w)<=2)
                fs=a*pow(abs(w),3)-5*a*pow(abs(w),2)+8*a*abs(w)-4*a;
            else
                fs=0;
            return fs;
    }
    
    HRESULT RotateZoom(PBYTE pbSrc,int iWidth,int iHeight,double dbRotate,double dbZoom,PBYTE pbTag);
    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
        int nRetCode = 0;
    
        setlocale(LC_ALL,"chs");
        HMODULE hModule = ::GetModuleHandle(NULL);
        if (hModule != NULL)
        {
            // initialize MFC and print and error on failure
            CImage cImage;
            HRESULT hResult;
            int        iWidth,iHeight,iBytePerPixel,iPitch;
            int        x,y;
            PBYTE    pbSrc=NULL,pbTag=NULL;
            PBYTE    pbImage=NULL;
            PDWORD    pdwImage=NULL;
            double    dbRotate=0,dbZoom=0;        
            do{
                if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
                {
                    // TODO: change error code to suit your needs
                    _tprintf(_T("Fatal Error: MFC initialization failed
    "));
                    nRetCode = 1;
                    break;
                }
                // TODO: code your application's behavior here.
                if(argc<5)
                {
                    _tprintf(_T("使用方法:RotateZoom 源图像文件 旋转角度 缩放倍数 输出文件
    "));
                    nRetCode= -1;
                    break;
                }
    
                _stscanf(argv[2],_T("%lf"),&dbRotate);
                _stscanf(argv[3],_T("%lf"),&dbZoom);
                if(!((dbRotate>0 && dbRotate<360) && (dbZoom>=0.25 && dbZoom<=16)))
                {
                    _tprintf(_T("“旋转角度” 或 “缩放倍数”参数错误!
    "));
                    nRetCode= -2;
                    break;
                }
    
                hResult=cImage.Load(argv[1]);
                if(hResult!=ERROR_SUCCESS)
                {
                    _tprintf(_T("源图像文件名错误!
    "));
                    nRetCode= -3;
                    break;
                }
    
                iWidth=cImage.GetWidth();
                iHeight=cImage.GetHeight();
                pbSrc = (PBYTE)malloc(iWidth*iHeight);//存原图数据大小没问题
                if(dbZoom>1) pbTag = (PBYTE)malloc(ceil(iWidth*dbZoom)*ceil(iHeight*dbZoom));
                else         pbTag = (PBYTE)malloc(iWidth*iHeight);
                if(pbSrc==NULL || pbTag==NULL )
                {
                    _tprintf(_T("内存申请错误!
    "));
                    nRetCode= -4;
                    break;
                }
                iPitch=cImage.GetPitch();
                iBytePerPixel=(cImage.GetBPP()+7)/8;
                if(iBytePerPixel==3)
                {
                    for(y=0;y<iHeight;y++)
                    {
                        pbImage=(PBYTE)(PBYTE(cImage.GetBits())+iPitch*y);//得到的是图像初始像素地址
                        for(x=0;x<iWidth;x++)
                        {
                            //pbSrc[y*iWidth+x]=pbImage[3*x];   //B
                            //pbSrc[y*iWidth+x]=pbImage[3*x+1]; //G
                            //pbSrc[y*iWidth+x]=pbImage[3*x+2]; //R
    
                            //pbSrc[y*iWidth+x]=pbImage[3*x];
                            //pbSrc[y*iWidth+x+1]=pbImage[3*x+1];
                            //pbSrc[y*iWidth+x+2]=pbImage[3*x+2];
    
                            pbSrc[y*iWidth+x]=(pbImage[3*x]*0.15+pbImage[3*x+1]*0.55+pbImage[3*x+2]*0.3);//转换成灰度就是单个像素了,分配大小还是原来的?。
                        }
                    }
                }
                cImage.Destroy();
                hResult=RotateZoom(pbSrc,iWidth,iHeight,dbRotate,dbZoom,pbTag);
                if(hResult!=ERROR_SUCCESS)
                {
                    _tprintf(_T("图像处理错误!
    "));
                    nRetCode= -5;
                    break;
                }
                iWidth=ceil(iWidth*dbZoom);
                iHeight=ceil(iHeight*dbZoom);
                cImage.Create(iWidth,-iHeight,32);
                iPitch=cImage.GetPitch();
                for(y=0;y<iHeight;y++)
                {
                    pdwImage=(PDWORD)(PBYTE(cImage.GetBits())+iPitch*y);
                    for(x=0;x<iWidth;x++)
                    {
                        pdwImage[x]=pbTag[y*iWidth+x]*0x10101;  
                    }
                }    
                CString csTagName=argv[4];
                csTagName.Trim();
                csTagName.MakeUpper();
                if(csTagName.Right(4)!=_T(".BMP") ) csTagName.Append(_T(".BMP"));
                hResult=cImage.Save(csTagName);
                if(hResult!=ERROR_SUCCESS)
                {
                    _tprintf(_T("图像结果保存错误!
    "));
                    nRetCode= -5;
                    break;
                }
                _tprintf(_T("图像处理成功!
    "));
                nRetCode= ERROR_SUCCESS;
                break;
            }while(0);
            if(pbSrc) free(pbSrc);
            if(pbTag) free(pbTag);
        }
        else
        {
            // TODO: change error code to suit your needs
            _tprintf(_T("Fatal Error: GetModuleHandle failed
    "));
            nRetCode = 1;
        }
        getchar();    
        return nRetCode;
    }
    HRESULT RotateZoom(PBYTE pbSrc,int iWidth,int iHeight,double dbRotate,double dbZoom,PBYTE pbTag)
    {
        int size;
        if(dbZoom>1)
        {
            size=iWidth*iHeight;
        }
        else
        {
            size=ceil(iWidth*dbZoom)*ceil(iHeight*dbZoom);
        }
        //旋转中心为图像中心
        double rx0=iWidth;  
        double ry0=iHeight; 
        double srcx,srcy,u,v;
        int xOr,yOr;
        dbRotate=dbRotate*3.1415926/180.0;
        for (int y=0;y<dbZoom*iHeight;y++)
        {
            for (int x=0;x<dbZoom*iWidth;x++)
            {
                srcx=(double)((x-rx0)*cos(dbRotate) - (y-ry0)*sin(dbRotate) + rx0) ;
                srcy=(double)((x-rx0)*sin(dbRotate) + (y-ry0)*cos(dbRotate) + ry0) ;
                srcx=srcx*1/dbZoom;
                srcy=srcy*1/dbZoom;
                xOr = floor(srcx);
                yOr = floor(srcy);
                u=srcx-xOr;
                v=srcy-yOr;
        //        if( !(xOr-1>=0 && xOr+2<=iWidth && yOr-1>=0 && yOr+2<=iHeight))
                if( !(srcx>=0 && srcx<=iWidth && srcy>=0 && srcy<=iHeight))
                    pbTag[y*2*iWidth+x]=0;//255
                else
                {   
                    pbTag[y*2*iWidth+x]=
                        pbSrc[(yOr-1)*iWidth+(xOr-1)]*fs(1+u)*fs(1+v)+
                        pbSrc[(yOr)*iWidth+(xOr-1)]*fs(1+u)*fs(v)+
                        pbSrc[(yOr+1)*iWidth+(xOr-1)]*fs(1+u)*fs(1-v)+
                        pbSrc[(yOr+2)*iWidth+(xOr-1)]*fs(1+u)*fs(2-v)+
                        
                        pbSrc[(yOr-1)*iWidth+(xOr)]*fs(u)*fs(1+v)+
                        pbSrc[(yOr)*iWidth+(xOr)]*fs(u)*fs(v)+
                        pbSrc[(yOr+1)*iWidth+(xOr)]*fs(u)*fs(1-v)+
                        pbSrc[(yOr+2)*iWidth+(xOr)]*fs(u)*fs(2-v)+
    
                        pbSrc[(yOr-1)*iWidth+(xOr+1)]*fs(1-u)*fs(1+v)+
                        pbSrc[(yOr)*iWidth+(xOr+1)]*fs(1-u)*fs(v)+
                        pbSrc[(yOr+1)*iWidth+(xOr+1)]*fs(1-u)*fs(1-v)+
                        pbSrc[(yOr+2)*iWidth+(xOr+1)]*fs(1-u)*fs(2-v)+
    
                        pbSrc[(yOr-1)*iWidth+(xOr+2)]*fs(2-u)*fs(1+v)+
                        pbSrc[(yOr)*iWidth+(xOr+2)]*fs(2-u)*fs(v)+
                        pbSrc[(yOr+1)*iWidth+(xOr+2)]*fs(2-u)*fs(1-v)+
                        pbSrc[(yOr+2)*iWidth+(xOr+2)]*fs(2-u)*fs(2-v);
    
                    if(pbTag[y*2*iWidth+x]>255)
                        pbTag[y*2*iWidth+x]=255;
                }
            }
        }
        //memcpy(pbTag,pbSrc,size);
        return ERROR_SUCCESS;
    }
  • 相关阅读:
    【Android】带底部指示的自定义ViewPager控件
    【Android】百度地图自定义弹出窗口
    【Linux配置】vim配置文件内容
    【Linux Tips】登陆,提示符,别名
    读《effective C++》2
    读《effective C++》1
    【PAT_Basic日记】1005. 继续(3n+1)猜想
    【PAT_Basic日记】1004 成绩排名
    【PAT_Basic日记】1002. 写出这个数
    【PAT_Basic日记】1001. 害死人不偿命的(3n+1)猜想
  • 原文地址:https://www.cnblogs.com/wxl845235800/p/9184620.html
Copyright © 2011-2022 走看看