如何创建膨胀效果是Java?

时间:2014-10-21 21:06:52

标签: java image effect

我正在尝试创建一个Java函数,通过将像素移动到图像的相对中心来对图像产生凸出效果。我首先取像素的(x,y)坐标,找到相对位移,x = x-(x / 2)并将其转换为极坐标形式[r cos(a),r sin (一个)]。 r由下式找到:r = Math.sqrt(x x + y y)。使用Math.atan2(y / x)找到角度a。使用r'= 2r ^ 1.5找到新的半径(r')。但是,来自[r cos(a),r sin(a)]的新x,y值超出了图像的尺寸,并且出现错误。

我犯了一个根本性的错误吗?

public void bulge()
  {
    double xval, yval = 0;
    //loop through the columns
    for(int x = 0; x < this.getWidth(); x++)
    {
      //loop through the rows
      for(int y = 0; y < this.getHeight(); y++)
      {
        int redValue, greenValue, blueValue = 0;
        double newRadius = 0;

        Pixel pixel = this.getPixel(x,y);
        redValue = pixel.getRed();
        greenValue = pixel.getGreen();
        blueValue = pixel.getBlue();

        xval = x - (x/2);
        yval = y - (y/2);

        double radius =  Math.sqrt(xval*xval + yval*yval);
        double angle = Math.atan2(yval, xval);
        newRadius = 2*(Math.pow(radius,1.5));
        xval = (int)(newRadius*Math.sin(angle));
        yval = (int)(newRadius*Math.cos(angle));

        Pixel pixelNewPos = this.getPixel((int)xval, (int)yval);
        pixelNewPos.setColor(new Color(redValue, greenValue, blueValue));
      }
    }
  }

2 个答案:

答案 0 :(得分:0)

  

我犯了一个根本性的错误吗?

在概念层面,是的。您的算法采用矩形图像并移动像素的位置以提供更大的非直视图像。显然,它不适合您的原始矩形。

因此,您需要剪切(即丢弃)落在矩形之外的像素,或者您需要使用更大的矩形,以便所有映射的像素都落在其中。

在后一种情况下,边缘会有间隙......如果你的转型正在做你声称它做的事情。矩形的非线性变换不会有直边。

答案 1 :(得分:0)

通过从图像B中的像素到图像A中的像素的反向变换,成功地将源图像A的变换应用到目标图像B要容易得多。

这意味着对于目标图像B中的每个像素,确定源图像A中对颜色有贡献的一个或多个像素。这样你就不会在目标图像中找到一堆未被触摸的像素。

作为使用2的线性缩放操作的示例,一个简单的实现可能如下所示:

for (int x = 0; x < sourceWidth; ++x) {
  for (int y = 0; y < sourceHeight; ++y) {
    Pixel sourcePixel = sourceImage.getPixel(x, y);
    int destPixelX = x * 2;
    int destPixelY = y * 2;
    destImage.setPixel(destPixelX, destPixelY, sourcePixel);
  }
}

从该代码中可以清楚地看出,目标图像中不会设置具有奇数X或Y值的像素。

更好的方法是这样的:

for (int x = 0; x < destWidth; ++x) {
  for (int y = 0; y < destHeight; ++y) {
    int sourcePixelX = x / 2;
    int sourcePixelY = y / 2;
    Pixel sourcePixel = sourceImage.getPixel(sourcePixelX, sourcePixelY);
    destImage.setPixel(x, y, sourcePixel);
  }
}

虽然这通常不是一个好的图像放大算法,但它确实显示了如何确保目标图像中的所有像素都已设置。