图片处理(Picture Lab)活动6:镜像图片

陈 欣发布

通用汽车实验室的汽车设计师们仅仅用粘土制作一半汽车的模型,然后将其贴合在垂直的镜面上即能看到整辆车的样子。如果我们也想看看图片镜像后(即把镜子置于图片正中让右侧成为左侧的倒影)的效果呢?

我们应该如何编写实现这一目标的method?构造算法(algorithm)——解决问题的一系列特定步骤——的方式之一是用更小且更简单的数据来测试。下图展示了如何让二维数组变得左右镜像对称起来。

你是否能分析出这一过程的算法?在不同尺寸的二维数组上测试你的算法。是否对奇数列的二维数组能正常工作呢?是否对偶数列的二维数组也能正常工作呢?

一种算法是循环遍历所有行以及一半列。你需要分别在图片的左右两侧各取到镜像的像素,它们在同一行,与中轴的距离相等(与左右边的距离也相等)。将右侧像素的颜色设为左侧像素即可。最右边的列号是列数(即宽度)减去一。所以当假定每行至少有三个像素时,第一个左侧像素会在[0][0]而第一个右侧像素会在[0][width-1]。第二个左侧像素会在[0][1]而对应的第二个右侧像素会在[0][width-1-1]。同理,第三个左侧像素会在[0][2]而对应的第三个右侧像素会在[0][width-1-2]。当左侧像素在[r][c]时,对应的右侧像素是[r][width-1-c]

以下method实现了这个算法。注意因为method并不对所有像素循环,因而不能使用嵌套for-each循环。

public void mirrorVertical()
{
  Pixel[][] pixels = this.getPixels2D();
  Pixel leftPixel = null;
  Pixel rightPixel = null;
  int width = pixels[0].length;
  for (int row = 0; row < pixels.length; row++)
  {
    for (int col = 0; col < width / 2; col++)
    {
      leftPixel = pixels[row][col];
      rightPixel = pixels[row][width - 1 - col];
      rightPixel.setColor(leftPixel.getColor());
    }
  }
}

你可以使用PictureTester中的testMirrorVertical method来测试它。

练习

  1. 编写mirrorVerticalRightToLeft method,将图片的左侧变为右侧的镜像。提示:你可以复制mirrorVertical的内容,修改method的一行即能实现新的功能。在PictureTester中编写名为testMirrorVerticalRightToLeftstatic method,并在main method中调用它测试新完成的函数。
  2. 编写mirrorHorizontal method,让图片变得以水平中线为轴镜像对称。向下图一样,让下侧变为上侧的镜像。在class PictureTester中创建一个测试新method的static method,并确保在PictureTestermain method中调用它。
  3. 编写mirrorHorizontalBotToTop method,将图片的上侧变为下侧的镜像。提示:你可以复制mirrorHorizontal 的内容,修改method的一行即能实现新的功能。在class PictureTester中创建一个测试新method的static method,并确保在PictureTestermain method中调用它。
  4. 挑战——分组研究mirrorDiagonal method的算法,将图片以对角线(对角线上像素的行号列号相等)为对称轴进行镜像。这就像在方形的纸左下角画上水彩画,再乘颜料未干时按对角线对折,让右上角也沾上对应的色彩一样。如下图所示,这会将左下角三角形区域复制到右上角。在class PictureTester中创建一个测试新method的static method,并确保在PictureTestermain method中调用它。

陈 欣

AADPS创始人

0 条评论

发表回复