RotateZoom.cpp 20180622

20180622代码加入随意变换图像大小

批处理框架先不看:-B src3.bmp 10 1 30 2  0.1 3 tar.bmp

src2.bmp 37.5 2.1 tar

// 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);
    }
    int newWidth=ceil(dbZoom*iWidth);
    //旋转中心为图像中心
    double rx0=ceil(dbZoom*iWidth)*0.5;  
    double ry0=ceil(dbZoom*iHeight)*0.5; 
    double srcx,srcy,u,v;
    int xOr,yOr;
    dbRotate=dbRotate*3.1415926/180.0;
    for (int y=0;y<ceil(dbZoom*iHeight);y++)
    {
        for (int x=0;x<ceil(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(u>0.5&&v>0.5)
            {
                xOr=xOr+1;
                yOr=yOr+1;
            }
            else if(u>0.5&&v<0.5)
            {
                xOr=xOr+1;
                yOr=yOr;
            }
            else if(u<0.5&&v>0.5)
            {
                xOr=xOr;
                yOr=yOr+1;
            }*/
    //        if( !(xOr-1>=0 && xOr+2<=iWidth && yOr-1>=0 && yOr+2<=iHeight))
            int newWidth=ceil(dbZoom*iWidth);
            if( !(srcx>=0 && srcx<=iWidth && srcy>=0 && srcy<=iHeight))
                {
                    pbTag[y*newWidth+x]=0;//255
                }
            else
            {   
                double middle=
                    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(middle<=255&&middle>=0)
                    pbTag[y*newWidth+x]=middle;
                else if(middle>255)
                    pbTag[y*newWidth+x]=255;
                else 
                    pbTag[y*newWidth+x]=0;
            }
        }
    }
    //memcpy(pbTag,pbSrc,size);
    return ERROR_SUCCESS;
}

在批处理框架中:

// 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        i,j,x,y,w,h;
        PBYTE    pbSrc=NULL,pbTag=NULL;
        PBYTE    pbImage=NULL;
        PDWORD    pdwImage=NULL;
        double    dbRotate=0,dbZoom=0;
        double    dbRotateStart=0,dbRotateEnd=0,dbRotateStep;
        double    dbZoomStart=0,dbZoomEnd=0,dbZoomStep;
        BOOL    bBenchWork=FALSE;
        CString csSrcName,csTagName,csNameRoot;
        TCHAR    *ptChar;
        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!=6 && argc!=10 )
            {
                _tprintf(_T("使用方法:
  RotateZoom -S 源图像文件 旋转角度 缩放倍数 输出文件
或:
  RotateZoom -B 源图像文件 旋转起始角度 步长 旋转终止角度 缩放起始倍数 步长 缩放终止倍数 输出文件
"));
                nRetCode= -1;
                break;
            }
            if(_tcsnicmp(argv[1],_T("-B"),2)==0)
            {
                bBenchWork=TRUE;
            }
            else if(_tcsnicmp(argv[1],_T("-S"),2)==0)
            {
                bBenchWork=FALSE;
            }
            else
            {
                _tprintf(_T("使用方法:
  RotateZoom -S 源图像文件 旋转角度 缩放倍数 输出文件
或:
RotateZoom -B 源图像文件 旋转起始角度 步长 旋转终止角度 缩放起始倍数 步长 缩放终止倍数 输出文件
"));
                nRetCode= -1;
                break;
            }
            if(bBenchWork)
            {
                csSrcName=argv[2];
                _stscanf(argv[3],_T("%lf"),&dbRotateStart);
                _stscanf(argv[4],_T("%lf"),&dbRotateStep);
                _stscanf(argv[5],_T("%lf"),&dbRotateEnd);

                _stscanf(argv[6],_T("%lf"),&dbZoomStart);
                _stscanf(argv[7],_T("%lf"),&dbZoomStep);
                _stscanf(argv[8],_T("%lf"),&dbZoomEnd);
                dbZoom=dbZoomStart>dbZoomEnd?dbZoomStart:dbZoomEnd;
                csTagName=argv[9];
                if(!((dbRotateStart>=0 && dbRotateStart<360) && 
                     (dbRotateEnd>=0 && dbRotateEnd<360)     &&
                     (dbZoomStart>=0.26 && dbZoomStart<=16)  && 
                     (dbZoomStart>=0.25 && dbZoomStart<=16)  &&
                     (dbRotateStep>=0.01) && (dbZoomEnd>=0.01)))
                {
                    _tprintf(_T("旋转角度范围(0~360),缩放倍数范围(0.25~16),步长范围(>=0.01)。输入参数超出范围!
"));
                    nRetCode= -2;
                    break;
                }    
            }
            else
            {
                csSrcName=argv[2];
                _stscanf(argv[3],_T("%lf"),&dbRotate);
                _stscanf(argv[4],_T("%lf"),&dbZoom);
                csTagName=argv[5];
                if(!((dbRotate>=0 && dbRotate<360) && (dbZoom>=0.25 && dbZoom<=16)))
                {
                    _tprintf(_T("旋转角度范围(0~360),缩放倍数范围(0.25~16)。输入参数超出范围!
"));
                    nRetCode= -2;
                    break;
                }            
            }



            hResult=cImage.Load(csSrcName);
            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]*0.15+pbImage[3*x+1]*0.55+pbImage[3*x+2]*0.3);//转换成灰度就是单个像素了,分配大小还是原来的?。
                    }
                }
            }
            cImage.Destroy();

            csTagName.Trim();
            csTagName.MakeUpper();        
            if(bBenchWork)
            {

                if(csTagName.Right(4)!=_T(".BMP") ) csNameRoot=csTagName;
                else csNameRoot=csTagName.Left (csTagName.GetLength()-4);
                j=0;
                for(dbZoom=dbZoomStart;dbZoom<=dbZoomEnd;dbZoom+=dbZoomStep)
                {
                    w=ceil(iWidth*dbZoom);
                    h=ceil(iHeight*dbZoom);
                    cImage.Create(w,-h,32);
                    iPitch=cImage.GetPitch();                    
                    for(dbRotate=dbRotateStart;dbRotate<=dbRotateEnd;dbRotate+=dbRotateStep)
                    {
                        hResult=RotateZoom(pbSrc,iWidth,iHeight,dbRotate,dbZoom,pbTag);
                        if(hResult!=ERROR_SUCCESS)
                        {
                            _tprintf(_T("图像处理错误!
"));
                            nRetCode= -5;
                            break;
                        }

                        for(y=0;y<h;y++)
                        {
                            pdwImage=(PDWORD)(PBYTE(cImage.GetBits())+iPitch*y);
                            for(x=0;x<w;x++)
                            {
                                pdwImage[x]=pbTag[y*w+x]*0x10101;  
                            }
                        }    
                        csTagName=csNameRoot;
                        csTagName.AppendFormat(_T("_Z%05.2f_R%06.2f.BMP"),dbZoom,dbRotate);            
                        hResult=cImage.Save(csTagName,Gdiplus::ImageFormatBMP);
                        if(hResult!=ERROR_SUCCESS)
                        {
                            _tprintf(_T("图像结果保存错误!
"));
                            nRetCode= -5;
                            break;
                        }
                        i=csTagName.GetLength();
                        ptChar=csTagName.GetBuffer(i+1);
                        ptChar[i]=_T('');
                        _tprintf(_T("图像处理成功!%s
"),ptChar);
                        csTagName.ReleaseBuffer();
                        nRetCode= ERROR_SUCCESS;
                        j++;
                    }
                    cImage.Destroy();
                    if(nRetCode!=ERROR_SUCCESS) break;
                }
                if(nRetCode==ERROR_SUCCESS) _tprintf(_T("批处理完成!共处理%d
"),j);
                else                        _tprintf(_T("批处理出错!已处理%d
"),j);
            }
            else
            {
                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;  
                    }
                }    
                if(csTagName.Right(4)!=_T(".BMP") ) csTagName.Append(_T(".BMP"));
                hResult=cImage.Save(csTagName,Gdiplus::ImageFormatBMP);
                if(hResult!=ERROR_SUCCESS)
                {
                    _tprintf(_T("图像结果保存错误!
"));
                    nRetCode= -5;
                    break;
                }
                i=csTagName.GetLength();
                ptChar=csTagName.GetBuffer(i+1);
                ptChar[i]=_T('');
                _tprintf(_T("图像处理成功!%s
"),ptChar);
                csTagName.ReleaseBuffer();
                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;
    }
    _tprintf(_T("按任意键退出!"));
    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);
    }
    int newWidth=ceil(dbZoom*iWidth);
    //旋转中心为图像中心
    double rx0=ceil(dbZoom*iWidth)*0.5;  
    double ry0=ceil(dbZoom*iHeight)*0.5; 
    double srcx,srcy,u,v;
    int xOr,yOr;
    dbRotate=dbRotate*3.1415926/180.0;
    for (int y=0;y<ceil(dbZoom*iHeight);y++)
    {
        for (int x=0;x<ceil(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;
            int newWidth=ceil(dbZoom*iWidth);
            if( !(xOr-1>=0 && xOr+2<=iWidth && yOr-1>=0 && yOr+2<=iHeight))
                {
                    pbTag[y*newWidth+x]=0;//255
                }
            else
            {   
                double middle=
                    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(middle<=255&&middle>=0)
                    pbTag[y*newWidth+x]=middle;
                else if(middle>255)
                    pbTag[y*newWidth+x]=255;
                else 
                    pbTag[y*newWidth+x]=0;
            }
        }
    }
    //memcpy(pbTag,pbSrc,size);
    return ERROR_SUCCESS;
}
原文地址:https://www.cnblogs.com/wxl845235800/p/9212783.html