用于从给定枢轴点缩放图像的算法

时间:2010-08-30 07:12:47

标签: image image-manipulation 2d scaling

使用图像中心作为枢轴点进行标准缩放,并且在所有维度上均匀。我想找出一种方法来从任意枢轴点缩放图像,使得更接近枢轴点的点比远离该点的点缩小。

2 个答案:

答案 0 :(得分:4)

好吧,我不知道你正在使用什么框架/库,但你可以把它想象成:

  • 翻译以使您的支点成为中心点
  • 标准缩放
  • 反向转换以使中心点成为原始枢轴点

平移和缩放是同构,因此您可以将它们表示为矩阵。每个变换都是一个矩阵,您可以将它们相乘以找到组合变换矩阵。所以:

  • T =转型
  • S = scalling
  • T'=相反的转变

如果将T.x应用为x点矢量,则会为您提供新坐标。同样适用于S.x。

因此,如果你想做那些操作,你必须这样做:T'。 (S.(T.x))

我认为您可以将操作关联起来,因此它与(T'.S.T).x

相同

如果您正在使用框架,则应用三个操作(或组合操作并应用)。 如果你正在使用原始数学...去矩阵方式:)

PS:如果你是手工做的话。我知道如果你正在缩放,你会想要找到一个转换点的原始点的坐标。因此,您可以迭代结果点(每个像素),并查看您必须使用的原始图像的坐标(或两者之间的点)。在这种情况下,你需要的是逆矩阵。所以不要使用S而是要使用S ^( - 1)。如果你知道你想要应用T'.S.T你可以找到这个结果矩阵,然后找到(T'.S.T)^( - 1)。然后你有你的逆矩阵来找到给定结果点的原始点。

答案 1 :(得分:0)

这是过于简单化,但应该可以帮助您入门。首先,由于标准重采样是统一的,因此实际上没有枢轴点的概念。如果有的话,它们通常只是从一个角落开始,因为以这种方式运行for循环更容易。

通常算法类似于这个伪代码

function resample (srcImg, dstSize) {
    dstImg = makeImage(dstSize)
    for (r = 0; r < dstSize.height; ++r) {
        for (c = 0; r < dstSize.width; ++c) {
            // getResampleLoc returns float coordinate
            resampleLoc = getResampleLoc(c, r, dstImg.size, srcImg.size)
            color = getColor(srcImg, resampleLoc)
            dstImg.setColor(c, r, color)
        }
    }
    return dstImage
} 

对于均匀重采样,getResampleLoc只是从dstImg大小到srcImg大小的简单x和y标度。它返回浮点坐标,传递给getColor。 getColor的实现决定了各种重采样算法。基本上,它以某种比例混合坐标周围的像素。实际上,可以通过优化来使getColor内部生成的信息在调用之间共享,但不要担心。

对你来说,你需要这样的东西:

function resample (srcImg, dstSize, pivotPt) {
    dstImg = makeImage(dstSize)
    for (r = 0; r < dstSize.height; ++r) {
        for (c = 0; r < dstSize.width; ++c) {
            // getResampleLoc returns float coordinate
            resampleLoc = getResampleLoc(c, r, dstImg.size, srcImg.size, pivotPt) 
            color = getColor(srcImg, resampleLoc)
            dstImg.setColor(c, r, color)
        }
    }
    return dstImage
} 

然后你只需要实现getResampleLoc来考虑pivotPt。可能最简单的事情是记录到边缘的距离。