⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rotatezoom.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
    srcy0_16 = Cy_16;
    for (y = 0;y < Dst->height;++y)
    {
        srcx_16 = srcx0_16;
        srcy_16 = srcy0_16;
        for (x = 0;x < Dst->width;++x)
        {
            srcx = (srcx_16 >> 16);
            srcy = (srcy_16 >> 16);
            if (RGBRotScaPixelsIsInPic(Src, srcx, srcy))
            {
                srcpixels = RGBRotScaPixels(Src, srcx, srcy);
                pDstLine[x] = *srcpixels;
            }
            srcx_16 += Ax_16;
            srcy_16 += Ay_16;
        }
        srcx0_16 += Bx_16;
        srcy0_16 += By_16;
        ((TUInt8*)pDstLine) += Dst->byte_width;
    }

}
#else

//函数假设以原图片的中心点坐标为旋转和缩放的中心,定点版本
void RGBRotScaPicRotaryInt(const tpicregion* Dst, const tpicregion* Src, double ZoomX, double ZoomY, double move_x, double move_y, double centerx0, double centery0, int RotateTimes)
{
    double rx0;
    double ry0;
    double tmprzoomxy = 1.0 / (ZoomX * ZoomY);
    double rZoomX = tmprzoomxy * ZoomY;
    double rZoomY = tmprzoomxy * ZoomX;
    long x;
    long y;
    long srcx0, srcx1;
    long srcy0, srcy1;
    long h, v;
    long coef1, coef2, coef3, coef4;
    long r, g, b;
    unsigned long p00, p01, p10, p11;
    targbmodel* srcpixels;
    long *pDstLine = (long*)Dst->pdata;
    int   RGBRotSca_gCosTable[4] = {1, 0, -1, 0};//0,PI/2,PI,PI*3/2
    int   RGBRotSca_gSinTable[4] = {0, 1, 0, -1};//0,PI/2,PI,PI*3/2
    long Ax_16 = (long)(rZoomX * RGBRotSca_gCosTable[RotateTimes & 0x3] * (1 << 16));
    long Ay_16 = (long)(rZoomX * RGBRotSca_gSinTable[RotateTimes & 0x3] * (1 << 16));
    long Bx_16 = (long)(-rZoomY * RGBRotSca_gSinTable[RotateTimes & 0x3] * (1 << 16));
    long By_16 = (long)(rZoomY * RGBRotSca_gCosTable[RotateTimes & 0x3] * (1 << 16));
    long Cx_16;
    long Cy_16;
    long srcx0_16;
    long srcy0_16;
    long srcx_16;
    long srcy_16;


    rx0 = centerx0;//Src->width*0.5;
    ry0 = centery0;//Src->height*0.5;//(rx0,ry0)为旋转中心

    Cx_16 = (long)((-(rx0 + move_x) * rZoomX * RGBRotSca_gCosTable[RotateTimes & 0x3] + (ry0 + move_y) * rZoomY * RGBRotSca_gSinTable[RotateTimes & 0x3] + rx0) * (1 << 16));
    Cy_16 = (long)((-(rx0 + move_x) * rZoomX * RGBRotSca_gSinTable[RotateTimes & 0x3] - (ry0 + move_y) * rZoomY * RGBRotSca_gCosTable[RotateTimes & 0x3] + ry0) * (1 << 16));

    srcx0_16 = Cx_16;
    srcy0_16 = Cy_16;
    for (y = 0;y < Dst->height;++y)
    {
        srcx_16 = srcx0_16;
        srcy_16 = srcy0_16;
        for (x = 0;x < Dst->width;++x)
        {
            srcx0 = (srcx_16 >> 16);
            srcx1 = srcx0 + 1;
            srcy0 = (srcy_16 >> 16);
            srcy1 = srcy0 + 1;
            h = ((srcx1 << 16) - srcx_16) >> 6;  // Q10
            v = ((srcy1 << 16) - srcy_16) >> 6;
            if (RGBRotScaPixelsIsInPic(Src, srcx0, srcy0))
            {
                p00 = *(unsigned long*)RGBRotScaPixels(Src, srcx0, srcy0);
                if (RGBRotScaPixelsIsInPic(Src, srcx1, srcy1))
                {
                    p01 = *(unsigned long*)RGBRotScaPixels(Src, srcx1, srcy0);
                    p10 = *(unsigned long*)RGBRotScaPixels(Src, srcx0, srcy1);
                    p11 = *(unsigned long*)RGBRotScaPixels(Src, srcx1, srcy1);

                    coef1 = v * h; // Q20
                    coef2 = v * (1024 - h);
                    coef3 = (1024 - v) * h;
                    coef4 = (1024 - v) * (1024 - h);

                    r = (coef1 * GET_R(p00) + coef2 * GET_R(p01) + coef3 * GET_R(p10) + coef4 * GET_R(p11)) >> 20;
                    g = (coef1 * GET_G(p00) + coef2 * GET_G(p01) + coef3 * GET_G(p10) + coef4 * GET_G(p11)) >> 20;
                    b = (coef1 * GET_B(p00) + coef2 * GET_B(p01) + coef3 * GET_B(p10) + coef4 * GET_B(p11)) >> 20;

                    pDstLine[x] = (b & 0xFF) | ((g & 0xFF) << 8) | ((r & 0xFF) << 16);
                }
                else
                {
                    pDstLine[x] = p00;
                }
            }
            srcx_16 += Ax_16;
            srcy_16 += Ay_16;
        }
        srcx0_16 += Bx_16;
        srcy0_16 += By_16;
        ((TUInt8*)pDstLine) += Dst->byte_width;
    }

}
#endif
rgbrotatescale* RGBRotScaTransform(rgbrotatescale* org, tRGBPicRotateZoomInOut* pRGBRotateScale, unsigned char *ImageLCDLogicBuf, int ScreenWidth, int ScreenHeight)
{
    tpicregion Src, Dst;
    float zoomx;
    float zoomy;
    int   rotatewidth;//源图像旋转后的宽度
    int   rotateheight;//源图像旋转后的高度
    int   zoomwidth;//原图像缩放后的图片宽度
    int   zoomheight;//原图像缩放后的图片高度
    int   movex;//x轴平移分量
    int   movey;//y轴平移分量
    double centerx0;//旋转中心点x坐标
    double centery0;//旋转中心点y坐标
    double zoomuint;//表示原图片尺寸缩小到屏幕尺寸时,缩小后图片宽度/原图片宽度的比值,该值为缩小的基本单位
    int   RGBRotSca_gCosTable[4] = {1, 0, -1, 0};//0,PI/2,PI,PI*3/2
    int   RGBRotSca_gSinTable[4] = {0, 1, 0, -1};//0,PI/2,PI,PI*3/2
    int RotateTimes;//顺时针旋转次数N,等价于N*PI/2
    if (!org)
        return (rgbrotatescale*)FALSE;

    Src.width = org->width;
    Src.height = org->height;
    Src.byte_width = org->width * sizeof(targbmodel);//Src.byte_width = (org->width * sizeof(targbmodel)+ 3) & ~3;//一行字节宽度按4对齐;
    Src.pdata = (targbmodel*)org->data;

    Dst.width = ScreenWidth;//targetbmp->width;
    Dst.height = ScreenHeight;//targetbmp->height;
    Dst.byte_width = (Dst.width * sizeof(targbmodel) + 3) & ~3;//一行字节宽度按4对齐
    Dst.pdata = (targbmodel*)(ImageLCDLogicBuf);//targetbmp->data;LCD_BUFFER

    RotateTimes = /*clockwise*/pRGBRotateScale->rotateangleindex;//计算顺时针/逆时针的角度索引
    if (pRGBRotateScale->rotateenable == 1)
    {//若启动旋转,则缩放的高度和宽度,取原图旋转后图片的高度和宽度
        rotatewidth = abs(Src.width * RGBRotSca_gCosTable[(RotateTimes) & 0x3] +
                          Src.height * RGBRotSca_gSinTable[RotateTimes & 0x3]);
        rotateheight = abs(Src.height * RGBRotSca_gCosTable[RotateTimes & 0x3] -
                           Src.width * RGBRotSca_gSinTable[RotateTimes & 0x3]);//计算顺时针/逆时针旋转的角度
    }
    else
    {//若没有启动旋转,则仍然采用原图的宽度和高度
        rotatewidth = Src.width;
        rotateheight = Src.height;
    }

    //旋转后的图片宽度、高度都小于等于屏幕的宽度、高度,则不放大也不缩小
    if ((rotatewidth <= Dst.width) && (rotateheight <= Dst.height))
    {//图片高宽都小于屏幕高宽时,显示原图尺寸大喜爱,且关闭缩放功能
        zoomx = 1.0;
        zoomy = 1.0;
        zoomuint = 1.0;
        pRGBRotateScale->zoomenable = 0;//关闭缩放功能
        pRGBRotateScale->moveenable = 0;//关闭平移功能
    }
    else
    {
        //只要高度、宽度中的一个超过屏幕的高度、宽度,就按照屏幕高度/图片高度,屏幕宽度/图片宽度中那个更小的比率来缩小,屏图比率越小表示缩小的幅度越大,缩小的越慢;
        zoomuint = zoomy = zoomx = MIN((float)Dst.width / rotatewidth, (float)Dst.height / rotateheight);
        if (pRGBRotateScale->zoomenable == 1)//触发了缩放按键功能,没有触发直接缩放到屏幕大小,zoomrate最大值为1.0/zoomuint,最小值为1.0,这个比率值是相对于屏幕尺寸图片为参照
        {
            zoomy = zoomx = (float)MIN(1.0, pRGBRotateScale->zoomrate * zoomuint);//最坏缩小到屏幕,一般按原图的0.5倍来缩小,1.0就是显示原图大小,但原图太大显示不下,只能以中心点坐标为准切割一块屏幕大小区域显示
        }
        zoomwidth = (int)(rotatewidth * zoomx);//根据缩小比率系数计算缩小后图片宽度
        zoomheight = (int)(rotateheight * zoomy);//根据缩小比率系数计算缩小后图片高度
    }

    if (pRGBRotateScale->moveenable == 1)
    {
        int movedx;
        int movedy;
        if (zoomwidth > Dst.width)
            //if(rotatewidth > Dst.width)
        {
            if (pRGBRotateScale->movedx < -(zoomwidth / 2 - Dst.width / 2))//x轴平移区间的左边界为-(zoomwidth/2-Dst.width/2)
            {
                movedx = -(zoomwidth / 2 - Dst.width / 2);
            }
            else
            {
                if (pRGBRotateScale->movedx > (zoomwidth / 2 - Dst.width / 2))//x轴平移区间的右边界为zoomwidth/2-Dst.width/2
                {
                    movedx = (zoomwidth / 2 - Dst.width / 2);
                }
                else
                {
                    movedx = pRGBRotateScale->movedx;//x轴平移分量在边界范围内就取该值
                }
            }
        }
        else
        {
            movedx = 0;//如果缩放后的图片宽度小于屏幕的宽度,则平移分量取0,即x轴不平移
        }

        if (zoomheight > Dst.height)
            //if(rotateheight > Dst.height)
        {
            if (pRGBRotateScale->movedy < -(zoomheight / 2 - Dst.height / 2))//y轴平移区间的左边界为-(zoomheight/2-Dst.height/2)
            {
                movedy = -(zoomheight / 2 - Dst.height / 2);
            }
            else
            {
                if (pRGBRotateScale->movedy > (zoomheight / 2 - Dst.height / 2))//y轴平移区间的右边界为zoomheight/2-Dst.height/2
                {
                    movedy = (zoomheight / 2 - Dst.height / 2);
                }
                else
                {
                    movedy = pRGBRotateScale->movedy;//y轴平移分量在边界范围内就取该值
                }
            }
        }
        else
        {
            movedy = 0;//如果缩放后的图片高度小于屏幕的高度,则平移分量取0,即y轴不平移
        }


        //若启动了平移标记,则设置相对于图片的中心而言的平移分量,要注意其可能超出平移边界
        movex = (Dst.width - Src.width) / 2 + (/*pRGBRotateScale->movexwise */ movedx);
        movey = (Dst.height - Src.height) / 2 + (/*pRGBRotateScale->moveywise */ movedy);
    }
    else
    {   //若没有启动平移,则以图片的中心为显示的中心轴
        movex = (Dst.width - Src.width) / 2;
        movey = (Dst.height - Src.height) / 2;
    }

    //设置旋转中心点坐标
    centerx0 = pRGBRotateScale->rcenterx0;
    centery0 = pRGBRotateScale->rcentery0;

    RGBRotScaPicRotaryInt(&Dst, &Src, zoomx, zoomy, movex, movey, centerx0, centery0, RotateTimes);

    return ((rgbrotatescale*)Dst.pdata);//targetbmp;
}

#endif



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -