将较小的网格投影到较大的网格上

时间:2017-12-01 10:20:33

标签: java math image-manipulation

我一直在编写一个有趣的图像编辑应用程序,一切都很好,但我遇到了缩放功能的问题。图像编辑器平面大小为512 x 512像素,但我想要编辑的图像只有16 x 16.我想知道如何将鼠标坐标投影到较小的图像上以逐像素编辑它。

我已经设计了这种算法。

/**
 * 
 * @param pointx The x position of the point thats being bound
 * @param pointy The y position of the point thats being bound
 * @param oldsizeX The old grid size x of which the point is currently in. ( eg  ==> 512*512)
 * @param oldsizeY The old grid size y of which the point is currently in. ( eg 512* ==> 512)
 * @param newsizeX The new grid size x for the new grid size of the point. ( eg  ==> 16*16)
 * @param newsizeY The new grid size y for the new grid size of the point. ( eg 16* ==> 16)
 * @param normalOffsetX The offset x, if any, the grid has in the normal plane ( eg ==> 32*32 @ (512*512))
 * @param normalOffsetY The offset y, if any, the grid has in the normal plane ( eg 32* ==> 32 @ (512*512)
 * @return A Vector2 containing the bound points in the new plane.
 */
public static Vector2 bindPoint(int pointx, int pointy, int oldsizeX, int oldsizeY, int newsizeX, int newsizeY,int normalOffsetX,int normalOffsetY) {
    Vector2 vec = new Vector2();
    int tileSizeX = oldsizeX / newsizeX;
    int tileSizeY = oldsizeY / newsizeY;

    int offsetX = normalOffsetX, offsetY = normalOffsetY;

    vec.x = (int) (pointx / 2) / (oldsizeX / tileSizeX) - (offsetX / tileSizeX);
    vec.y = (int) (pointy / 2) / (oldsizeY / tileSizeY) - (offsetY / tileSizeY);

    if(pointx >= normalOffsetX && pointx <= normalOffsetX + oldsizeX && pointy >= normalOffsetY && pointy <= normalOffsetY + oldsizeY) {
        return vec;
    }else {
        return new Vector2(-1,-1);
    }
}

只要较小的分辨率是16x16并且我发现如果我将pointX和pointY除法后的2更改为0.5并且32x32的图像有效,则此方法有效。我想知道的是,如果有更好的方法,那么我可以在任何缩放级别使用任何尺寸的图像?

2 个答案:

答案 0 :(得分:0)

您不应使用integers来表示该职位。在进行计算时,请改用double。最后,当您计算了所有内容并需要像素值时,请将double四舍五入为integer。否则你将失去所有地方的精确度(这解释了你看到的问题)。

根据您使用括号的方式,您会得到不同的结果。例如,从数学的角度来看,下面Systems out应该给你相同的结果,但他们不会:

    int i = 700;
    int j = 70;
    int k = 30;
    System.out.println((i / 2) / (j / k)); --> 175
    System.out.println(i / 2 / j * k); --> 150

答案 1 :(得分:0)

我在自己的哈哈上找到了它,抱歉,它迟到了,我间隔开了,忘记了比例。

以下是其他需要它的人的答案!

/**
 * 
 * @param pointx The x position of the point thats being bound
 * @param pointy The y position of the point thats being bound
 * @param oldsizeX The old grid size x of which the point is currently in. ( eg  ==> 512*512)
 * @param oldsizeY The old grid size y of which the point is currently in. ( eg 512* ==> 512)
 * @param newsizeX The new grid size x for the new grid size of the point. ( eg  ==> 16*16)
 * @param newsizeY The new grid size y for the new grid size of the point. ( eg 16* ==> 16)
 * @param normalOffsetX The offset x, if any, the grid has in the normal plane ( eg ==> 32*32 @ (512*512))
 * @param normalOffsetY The offset y, if any, the grid has in the normal plane ( eg 32* ==> 32 @ (512*512)
 * @return A Vector2 containing the bound points in the new plane.
 */
public static Vector2 bindPoint(int pointx, int pointy, int oldsizeX, int oldsizeY, int newsizeX, int newsizeY,int normalOffsetX,int normalOffsetY) {
    Vector2 vec = new Vector2();
    int tileSizeX = oldsizeX / newsizeX;
    int tileSizeY = oldsizeY / newsizeY;
    int offsetX = normalOffsetX, offsetY = normalOffsetY;

    vec.x = (int) Math.floor(pointx * ((float) newsizeX) / (float) oldsizeX) - (offsetX / tileSizeX);
    vec.y = (int) Math.floor(pointy * ((float) newsizeY) / (float) oldsizeY) - (offsetY / tileSizeY);
    return vec;
}