图像旋转中原图16×16分块测试2,映射后插入图中,测试边界信息

// 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\n"));
                nRetCode = 1;
                break;
            }
            // TODO: code your application‘s behavior here.
            if(argc!=6 && argc!=10 )
            {
                _tprintf(_T("使用方法:\n  RotateZoom -S 源图像文件 旋转角度 缩放倍数 输出文件\n或:\n  RotateZoom -B 源图像文件 旋转起始角度 步长 旋转终止角度 缩放起始倍数 步长 缩放终止倍数 输出文件\n"));
                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("使用方法:\n  RotateZoom -S 源图像文件 旋转角度 缩放倍数 输出文件\n或:\nRotateZoom -B 源图像文件 旋转起始角度 步长 旋转终止角度 缩放起始倍数 步长 缩放终止倍数 输出文件\n"));
                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)。输入参数超出范围!\n"));
                    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)。输入参数超出范围!\n"));
                    nRetCode= -2;
                    break;
                }
            }

            hResult=cImage.Load(csSrcName);
            if(hResult!=ERROR_SUCCESS)
            {
                _tprintf(_T("源图像文件名错误!\n"));
                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("内存申请错误!\n"));
                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("图像处理错误!\n"));
                            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("图像结果保存错误!\n"));
                            nRetCode= -5;
                            break;
                        }
                        i=csTagName.GetLength();
                        ptChar=csTagName.GetBuffer(i+1);
                        ptChar[i]=_T(‘\0‘);
                        _tprintf(_T("图像处理成功!%s\n"),ptChar);
                        csTagName.ReleaseBuffer();
                        nRetCode= ERROR_SUCCESS;
                        j++;
                    }
                    cImage.Destroy();
                    if(nRetCode!=ERROR_SUCCESS) break;
                }
                if(nRetCode==ERROR_SUCCESS) _tprintf(_T("批处理完成!共处理%d\n"),j);
                else                        _tprintf(_T("批处理出错!已处理%d\n"),j);
            }
            else
            {
                hResult=RotateZoom(pbSrc,iWidth,iHeight,dbRotate,dbZoom,pbTag);
                if(hResult!=ERROR_SUCCESS)
                {
                    _tprintf(_T("图像处理错误!\n"));
                    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("图像结果保存错误!\n"));
                    nRetCode= -5;
                    break;
                }
                i=csTagName.GetLength();
                ptChar=csTagName.GetBuffer(i+1);
                ptChar[i]=_T(‘\0‘);
                _tprintf(_T("图像处理成功!%s\n"),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\n"));
        nRetCode = 1;
    }
    _tprintf(_T("按任意键退出!"));
    getchar();
    return nRetCode;
}
HRESULT RotateZoom(PBYTE pbSrc,int iWidth,int iHeight,double dbRotate,double dbZoom,PBYTE pbTag)
{
    double phase[33]={0};//16相位,包含端点存在33个距离
    for (int i=0;i<33;i++)
    {
        double i2=1.0*i;
        phase[i]=fs(i2/16);
    }
    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;
    int xo=250,yo=250;
         for(int y=yo;y<yo+250;y++)
            {
                for(int x=xo;x<xo+250;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 phasex=floor(16*u+0.5);//16相位
                    int phasey=floor(16*v+0.5);

                    double A1,B1,C1,D1,A2,B2,C2,D2;

                    A1=phase[16+phasex];
                    B1=phase[phasex];
                    C1=phase[16-phasex];
                    D1=phase[32-phasex];

                    A2=phase[16+phasey];
                    B2=phase[phasey];
                    C2=phase[16-phasey];
                    D2=phase[32-phasey];

                    int newWidth=ceil(dbZoom*iWidth);
                    int block_numx=ceil((xOr+1.0)/16);
                    int block_numy=ceil((yOr+1.0)/16);

                    double blockSrc[256]={0};
                    int newcount=0;
                    //int k=0,l=0;
                    //分块存储进数组blockSrc[]中
                    for(int k=0;k<16;k++)
                    {
                        for(int l=0;l<16;l++)
                        {
                            int oldcount=(16*block_numy-16+k)*iWidth+16*block_numx-16+l;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

                            blockSrc[newcount]=pbSrc[oldcount];
                            //pbTag[newcount]=pbSrc[oldcount];

                            newcount++;
                            //cout<<oldcount<<endl;
                        }

                    }//分块存入完毕
                    if( !(xOr-1>=0 && xOr+2<=iWidth && yOr-1>=0 && yOr+2<=iHeight))
                    {
                        pbTag[y*newWidth+x]=0;//255
                    }
                    else
                    {
                        //映射到16×16块内的初始点位置
                        xOr=xOr-(16*block_numx-16);
                        yOr=yOr-(16*block_numy-16);
                        //if(xOr>=1 && xOr<=14 && yOr>=1 && yOr<=14)
                        pbTag[y*newWidth+x]=blockSrc[yOr*16+xOr];
                        //else
                        //    pbTag[y*newWidth+x]=255;
                    }

                }

            }

    return ERROR_SUCCESS;
}

测试1:-S src3.bmp 22.5 2 tar

pbTag[y*newWidth+x]=blockSrc[yOr*16+xOr];

处理后图起始点(250,250),区域250×250区域;

直接赋值过去,由于图像是放大二倍,效果近似最近邻插值。

测试2:加入4×4区域内边界判别

边界待定值赋白色

if(xOr>=1 && xOr<=14 && yOr>=1 && yOr<=14)
  pbTag[y*newWidth+x]=blockSrc[yOr*16+xOr];
else
  pbTag[y*newWidth+x]=255;

测试3:边界待定值赋黑色

if(xOr>=1 && xOr<=14 && yOr>=1 && yOr<=14)
  pbTag[y*newWidth+x]=blockSrc[yOr*16+xOr];
else
  pbTag[y*newWidth+x]=0;

测试4:扩展为全图进行处理

int xo=0,yo=0;
for(int y=yo;y<ceil(dbZoom*iHeight);y++)
  {
    for(int x=xo;x<ceil(dbZoom*iWidth);x++)
      {

原因在于映射回的初始点(xOr、yOr)没有事先判断,

要先判断是否映射落回原图点上再进行后续计算,因为后续用到了xOr、yOr的值。

代码如下:(还需要再处理下边界处、引入双三次插值 就OK了)

// 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\n"));
                nRetCode = 1;
                break;
            }
            // TODO: code your application‘s behavior here.
            if(argc!=6 && argc!=10 )
            {
                _tprintf(_T("使用方法:\n  RotateZoom -S 源图像文件 旋转角度 缩放倍数 输出文件\n或:\n  RotateZoom -B 源图像文件 旋转起始角度 步长 旋转终止角度 缩放起始倍数 步长 缩放终止倍数 输出文件\n"));
                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("使用方法:\n  RotateZoom -S 源图像文件 旋转角度 缩放倍数 输出文件\n或:\nRotateZoom -B 源图像文件 旋转起始角度 步长 旋转终止角度 缩放起始倍数 步长 缩放终止倍数 输出文件\n"));
                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)。输入参数超出范围!\n"));
                    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)。输入参数超出范围!\n"));
                    nRetCode= -2;
                    break;
                }
            }

            hResult=cImage.Load(csSrcName);
            if(hResult!=ERROR_SUCCESS)
            {
                _tprintf(_T("源图像文件名错误!\n"));
                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("内存申请错误!\n"));
                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("图像处理错误!\n"));
                            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("图像结果保存错误!\n"));
                            nRetCode= -5;
                            break;
                        }
                        i=csTagName.GetLength();
                        ptChar=csTagName.GetBuffer(i+1);
                        ptChar[i]=_T(‘\0‘);
                        _tprintf(_T("图像处理成功!%s\n"),ptChar);
                        csTagName.ReleaseBuffer();
                        nRetCode= ERROR_SUCCESS;
                        j++;
                    }
                    cImage.Destroy();
                    if(nRetCode!=ERROR_SUCCESS) break;
                }
                if(nRetCode==ERROR_SUCCESS) _tprintf(_T("批处理完成!共处理%d\n"),j);
                else                        _tprintf(_T("批处理出错!已处理%d\n"),j);
            }
            else
            {
                hResult=RotateZoom(pbSrc,iWidth,iHeight,dbRotate,dbZoom,pbTag);
                if(hResult!=ERROR_SUCCESS)
                {
                    _tprintf(_T("图像处理错误!\n"));
                    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("图像结果保存错误!\n"));
                    nRetCode= -5;
                    break;
                }
                i=csTagName.GetLength();
                ptChar=csTagName.GetBuffer(i+1);
                ptChar[i]=_T(‘\0‘);
                _tprintf(_T("图像处理成功!%s\n"),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\n"));
        nRetCode = 1;
    }
    _tprintf(_T("按任意键退出!"));
    getchar();
    return nRetCode;
}
HRESULT RotateZoom(PBYTE pbSrc,int iWidth,int iHeight,double dbRotate,double dbZoom,PBYTE pbTag)
{
    double phase[33]={0};//16相位,包含端点存在33个距离
    for (int i=0;i<33;i++)
    {
        double i2=1.0*i;
        phase[i]=fs(i2/16);
    }
    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;
    int xo=0,yo=0;
         for(int y=yo;y<ceil(dbZoom*iHeight);y++)
            {
                for(int x=xo;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);
                    if( !(xOr-1>=0 && xOr+2<=iWidth && yOr-1>=0 && yOr+2<=iHeight))
                    {
                        pbTag[y*newWidth+x]=0;//255
                    }
                    else
                    {
                        u=srcx-xOr;
                        v=srcy-yOr;
                        int phasex=floor(16*u+0.5);//16相位
                        int phasey=floor(16*v+0.5);

                        double A1,B1,C1,D1,A2,B2,C2,D2;
                        A1=phase[16+phasex];
                        B1=phase[phasex];
                        C1=phase[16-phasex];
                        D1=phase[32-phasex];
                        A2=phase[16+phasey];
                        B2=phase[phasey];
                        C2=phase[16-phasey];
                        D2=phase[32-phasey];

                        int newWidth=ceil(dbZoom*iWidth);
                        int block_numx=ceil((xOr+1.0)/16);
                        int block_numy=ceil((yOr+1.0)/16);

                        double blockSrc[256]={0};
                        int newcount=0;
                        //int k=0,l=0;
                        //分块存储进数组blockSrc[]中
                        for(int k=0;k<16;k++)
                        {
                            for(int l=0;l<16;l++)
                            {
                                int oldcount=(16*block_numy-16+k)*iWidth+16*block_numx-16+l;
                                blockSrc[newcount]=pbSrc[oldcount];
                                //pbTag[newcount]=pbSrc[oldcount];
                                newcount++;
                                //cout<<oldcount<<endl;
                            }
                        }//分块存入完毕
                        //映射到16×16块内的初始点位置
                        xOr=xOr-(16*block_numx-16);
                        yOr=yOr-(16*block_numy-16);
                        if(xOr>=1 && xOr<=14 && yOr>=1 && yOr<=14)
                            pbTag[y*newWidth+x]=blockSrc[yOr*16+xOr];
                        else
                            pbTag[y*newWidth+x]=255;
                    }
                }
            }
    return ERROR_SUCCESS;
}

原文地址:https://www.cnblogs.com/wxl845235800/p/9367785.html

时间: 2024-10-23 09:38:15

图像旋转中原图16×16分块测试2,映射后插入图中,测试边界信息的相关文章

十字链表的方式实现在头部插入图中节点

#include<stdio.h> #include<malloc.h> #define MAX_VERTEX_NUM 20 typedef struct ArcBox{ int tailvex,headvex;//该弧的头和尾定点的位置 struct ArcBox *hlink,*tlink;//分别为弧头和弧尾相同的弧的链域 int *info; }ArcBox; typedef struct VexNode //顶点结点 { char data; //顶点信息(标识) Arc

.NET中利用反射来实现自动映射两个对象中的数据成员

在以前的项目开发之中,经常会遇到这样一个问题:比如在外面项目的架构设计之中,我们采用MVC和EntityFramework来构建一个Web应用程序.比如我们采用常用的多层架构,例如有Presentation层.BusinessLogic层.DataAccess层等,各层之间是相对独立并且职责分明的.比如我们在Presentation层中会定义ViewModel,在DataAccess层中的DbContext部分又会由EntityFramework来自动生成StorageModel,或者叫做Dat

三维封闭曲线着色,在图中插入子图,指定显示的图例。

立体图像着色 主要使用函数fill3() 功能:给三维图像着色 调用规则:fill3(X, Y, Z, C, 'PropertyName', PropertyValue) 输入 X.Y .Z指坐标 C:颜色 'PropertyName':可选属性,主要使用了透明度 alpha 可以使用 fig = get(gcf) 获取图形对象的属性和值: ax = get(gca) 获取坐标轴的属性和值 使用fill3函数绘制一个立方体,并指定每个面的颜色,代码如下: figure(1);clf;hold o

java 数据结构 图中使用的一些常用算法 图的存储结构 邻接矩阵:图的邻接矩阵存储方式是用两个数组来标示图。一个一位数组存储图顶点的信息,一个二维数组(称为邻接矩阵)存储图中边或者弧的信息。 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 实例如下,左图是一个无向图。右图是邻接矩阵表示:

以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示一个图,V是图G中顶点的集合,E是图G中边的集合. 无边图:若顶点Vi到Vj之间的边没有方向,则称这条边为无项边(Edge),用序偶对(Vi,Vj)标示. 对于下图无向图G1来说,G1=(V1, {E1}),其中顶点集合V1={A,B,C,D}:边集合E1={(A,B),(B,C),(C,D),(D,A),(A,C)}: 有向图:若

多张表中数据组合后插入新表的方法

以mysql为例. 遇到这个问题的时候最先想到的方法就是先从各个表中查询出相应的数据后使用程序循环遍历组装后在插入到数据库中.这是最直观的解决办法,但是这个方法处理超大结果集的时候就出现问题,例如:超出内存限制,运行时间过长等等... 这时使用另外一种方法应该会有帮助,那就是使用mysql的on duplicate key update方法来分步骤组合数据. 现在有3张表a,b,c.每个表的结构如下: a表包含字段:id,a,b,c: b表包含字段:aID,d,e,f:字段aID对应表a中的id

Floyd-Warshall求图中任意两点的最短路径

原创 除了DFS和BFS求图中最短路径的方法,算法Floyd-Warshall也可以求图中任意两点的最短路径. 从图中任取两点A.B,A到B的最短路径无非只有两种情况: 1:A直接到B这条路径即是最短路径(前提是存在此路径): 2:A先通过其他点,再由其他点到B. 我们并不知道A是否需要通过其他点间接到达B,所以只能比较,用A到B的直接路径和A先通过其他点 再间接到达B的路径长度进行比较,然后更新为较小值. 上图中若要求顶点4到顶点3的最短路径,可以比较顶点4直接到3的路径和顶点4先到1,再到3

【OpenCV】图像旋转详解,边缘用黑色填充

项目要用到图像旋转,OpenCV里面居然没有专门封装好的函数,只好自己写了.根据<learnning OpenCV>发现效果不是很理想,旋转后图像大小不变,可是图像却被裁减了. 例子如下: int main( int argc, char** argv ) { IplImage* src=cvLoadImage("C:\\Users\\Liu\\Desktop\\bridge.bmp",1); IplImage* dst = cvCloneImage( src ); int

用OpenCV实现Photoshop算法(一): 图像旋转

最近学习了OpenCV,于是想用它实现Photoshop的主要功能,用于照片处理. 对于一张照片,PS的一般处理步骤包括: 1, 旋转图片,校正位置. 2,剪切,调整大小,重新构图. 3,调整色阶.曲线,使图片曝光正确.对比适中. 4,调整对比度.饱和度 5,印章去掉不想要的东西,液化调整形体线条 6,对于人像图片,美肤.美白 7, 用色彩平衡.可选颜色等调整色调,形成照片调性 8,加一些光效 9,锐化 以后的一系列博文将采用OpenCV逐一实现Photoshop的算法和功能, 并用计算机视觉人

图像处理 基于Visual C++编程 学习笔记 (4)图像旋转

图像旋转 imgrotation 根据输入的角度进行旋转变换 很简单,套公式. 遍历输出的图像的像素,去原图中找对应像素,超出边界置0 如果遍历原图像素,去构建输出图像像素则会有很多噪声,因为浮点数计算的误差 数据校验及数据转换 void CBMPDlg::OnRota() { // TODO: Add your control notification handler code here CDC *pDC = m_image1.GetDC(); CRect myRECT; m_image1.G