• 代码记录——phase16,block32


    HRESULT RotateZoom(PBYTE pbSrc,int iWidth,int iHeight,double dbRotate,double dbZoom,PBYTE pbTag)
    {
        //int phase[17]={0};//8相位,包含端点存在17个距离      //16 
        //for (int i=0;i<17;i++)
        //{
        //    double i2=1.0*i;
        //    phase[i]=fs(i2/8)*1024;
        //}
        int phase[17]={1024,987,888,745,576,399,232,93,0,-49,-72,-75,-64,-45,-24,-7,0};
    
        int src1x,src1y,src2x,src2y,src3x,src3y,src4x,src4y;
        int drcx[4],drcy[4];
        int angl=724;//旋转45度
        int middle_height=1024;
        int middle_width=1280;
        int rx=640;
        int ry=512;
    
        int newheight=1640;
        int newwidth=1640;
        int rx0=820;  //插值放大后图像的旋转中心
        int ry0=820;
        for(int y=0;y<512;y=y+32)
        {
            for(int x=0;x<640;x=x+32)
            {
                //正向映射入大图像中分块图像所对应的像素点            
                src1x=x;src1y=y;src2x=x+31;src2y=y;src3x=x;src3y=y+31;src4x=x+31;src4y=y+31;
                //正向映射公式
                int a=dbZoom;
                drcx[0]=(a*src1x-rx)*angl+(a*src1y-ry)*angl+rx0*1024;
                drcy[0]=-(a*src1x-rx)*angl+(a*src1y-ry)*angl+ry0*1024;
                drcx[1]=(a*src2x-rx)*angl+(a*src2y-ry)*angl+rx0*1024;
                drcy[1]=-(a*src2x-rx)*angl+(a*src2y-ry)*angl+ry0*1024;
                drcx[2]=(a*src3x-rx)*angl+(a*src3y-ry)*angl+rx0*1024;
                drcy[2]=-(a*src3x-rx)*angl+(a*src3y-ry)*angl+ry0*1024;
                drcx[3]=(a*src4x-rx)*angl+(a*src4y-ry)*angl+rx0*1024;
                drcy[3]=-(a*src4x-rx)*angl+(a*src4y-ry)*angl+ry0*1024;
                //获得分块图像大范围
                drcx[0]=(int)(drcx[0]/1024);//截后10位处理?
                drcy[0]=(int)(drcy[0]/1024);
                drcx[1]=(int)(drcx[1]/1024);
                drcy[1]=(int)(drcy[1]/1024);
                drcx[2]=(int)(drcx[2]/1024);
                drcy[2]=(int)(drcy[2]/1024);
                drcx[3]=(int)(drcx[3]/1024);
                drcy[3]=(int)(drcy[3]/1024);
                //放大二倍有边框,不旋转时+1可处理
                int max_x,max_y,min_x,min_y;
                int srcx,srcy;
                max_x=drcx[0];max_y=drcy[0];min_x=drcx[0];min_y=drcy[0];
                for (int i=0;i<4;i++)
                {
                    if (min_x>drcx[i])
                        min_x=drcx[i];
                    if (min_y>drcy[i])
                        min_y=drcy[i];
                }
                min_x=min_x-1;min_y=min_y-1;
                for (int i=0;i<4;i++)
                {
                    if (max_x<drcx[i])
                        max_x=drcx[i];
                    if (max_y<drcy[i])
                        max_y=drcy[i];
                }
                max_x=min_x+96-1;max_y=max_y+1;
    
                //将范围内的点映射回原图中 同时旋转插值
                for (int j=min_y;j<=max_y;j++)
                {
                    for (int i=min_x;i<=max_x;i++)
                    {
                        //将点映射回原图中
                        srcx=((i-rx0)*angl-(j-ry0)*angl+rx*1024)/2048;
                        srcy=((i-rx0)*angl+(j-ry0)*angl+ry*1024)/2048;
                        if ((srcx>=x-2)&&(srcx<=x+33)&&(srcy>=y-2)&&(srcy<=y+33)&&(srcx>=2)&&(srcy>=2)&&(srcx<=iWidth-2)&&(srcy<=iHeight-2))/*&&(i>=0)&&(j>=0)*/
                        {
                            //映射后位置判断区别可能有误
                            //if(srcx>x+31)
                            //{
                            //    srcx=x+31;
                            //}
                            //if(srcy>y+31)
                            //{
                            //    srcy=y+31;
                            //}
    
                            //if(srcx<x-1)
                            //{
                            //    srcx=x-1;
                            //}
                            //if(srcy<y-1)
                            //{
                            //    srcy=y-1;
                            //}
    
                            //插值:
                            //计算整数部分和小数部分
                            int xOr = floor((double)srcx);
                            int yOr = floor((double)srcy);
                            double u=srcx-xOr;
                            double v=srcy-yOr;
                            //查表双三插值
                            int phasex=8*u;//8相位
                            int phasey=8*v;
                            int A1,B1,C1,D1,A2,B2,C2,D2;  //计算每个点的插值系数
                            A1=phase[8+phasex];B1=phase[phasex];C1=phase[8-phasex];D1=phase[16-phasex];
                            A2=phase[8+phasey];B2=phase[phasey];C2=phase[8-phasey];D2=phase[16-phasey];
    
                            //由src计算块编号,使用对应编号块内的相对位置
                            int xnum,ynum;
                            int x_upleft,y_upleft;//左上起始点坐标
                            int x_shift,y_shift;
    
                            xnum=floor(srcx/32.0)+1;
                            ynum=floor(srcy/32.0)+1;
                            x_upleft=(xnum-1)*32;
                            y_upleft=(ynum-1)*32;
    
                            int imgsrc[1024]={255};//36*36,32*32
                            int ijk=0;
    
                            for (int n=0;n<32;n++)
                            {    
                                for (int m=0;m<32;m++)
                                {
                                            imgsrc[ijk]=pbSrc[(y_upleft+n)*iWidth+x_upleft+m];
                                            ijk++;
                                }
    
                            }
                                //块内相对偏移位置
                                x_shift= xOr-x_upleft;
                                y_shift= yOr-y_upleft;
    
    
                                int middle=imgsrc[(y_shift)*32+(x_shift)];
    
                                /*imgsrc[(yOr-1)*iWidth+(xOr-1)]*A1*A2+imgsrc[(yOr)*iWidth+(xOr-1)]*A1*B2+imgsrc[(yOr+1)*iWidth+(xOr-1)]*A1*C2+imgsrc[(yOr+2)*iWidth+(xOr-1)]*A1*D2+
                                imgsrc[(yOr-1)*iWidth+(xOr)]*B1*A2+imgsrc[(yOr)*iWidth+(xOr)]*B1*B2+imgsrc[(yOr+1)*iWidth+(xOr)]*B1*C2+imgsrc[(yOr+2)*iWidth+(xOr)]*B1*D2+
                                imgsrc[(yOr-1)*iWidth+(xOr+1)]*C1*A2+imgsrc[(yOr)*iWidth+(xOr+1)]*C1*B2+imgsrc[(yOr+1)*iWidth+(xOr+1)]*C1*C2+imgsrc[(yOr+2)*iWidth+(xOr+1)]*C1*D2+
                                imgsrc[(yOr-1)*iWidth+(xOr+2)]*D1*A2+imgsrc[(yOr)*iWidth+(xOr+2)]*D1*B2+imgsrc[(yOr+1)*iWidth+(xOr+2)]*D1*C2+imgsrc[(yOr+2)*iWidth+(xOr+2)]*D1*D2;*/
    
    
                                /*int middle=pbSrc[(yOr-1)*iWidth+(xOr-1)]*A1*A2+pbSrc[(yOr)*iWidth+(xOr-1)]*A1*B2+pbSrc[(yOr+1)*iWidth+(xOr-1)]*A1*C2+pbSrc[(yOr+2)*iWidth+(xOr-1)]*A1*D2+
                                pbSrc[(yOr-1)*iWidth+(xOr)]*B1*A2+pbSrc[(yOr)*iWidth+(xOr)]*B1*B2+pbSrc[(yOr+1)*iWidth+(xOr)]*B1*C2+pbSrc[(yOr+2)*iWidth+(xOr)]*B1*D2+
                                pbSrc[(yOr-1)*iWidth+(xOr+1)]*C1*A2+pbSrc[(yOr)*iWidth+(xOr+1)]*C1*B2+pbSrc[(yOr+1)*iWidth+(xOr+1)]*C1*C2+pbSrc[(yOr+2)*iWidth+(xOr+1)]*C1*D2+
                                pbSrc[(yOr-1)*iWidth+(xOr+2)]*D1*A2+pbSrc[(yOr)*iWidth+(xOr+2)]*D1*B2+pbSrc[(yOr+1)*iWidth+(xOr+2)]*D1*C2+pbSrc[(yOr+2)*iWidth+(xOr+2)]*D1*D2;
                                */
                            //middle=middle/(1024*1024);
    
    
                            if(middle<=255&&middle>=0)
                            pbTag[j*newwidth+i]=middle;
                            else if(middle>255)
                                pbTag[j*newwidth+i]=255;
                            else 
                                pbTag[j*newwidth+i]=0;
                        }
                    }
                }
            }            
        }
        return ERROR_SUCCESS;
    }
  • 相关阅读:
    JAVA微信公众号网页开发——获取公众号关注的所有用户
    删除mysl
    sql语言(mysql)
    mycat读写分离
    mysql双主双从技术
    实用的10个日志处理案例
    ansible基本操作
    MySQL改密
    mysql源码包安装
    ftp搭建mysql服务器
  • 原文地址:https://www.cnblogs.com/wxl845235800/p/10655334.html
Copyright © 2020-2023  润新知