【问题标题】:How to condense code : know the limits of an image after rotation如何压缩代码:知道旋转后图像的限制
【发布时间】:2024-01-05 09:56:01
【问题描述】:

我是 Java 初学者。

我有一张我知道行数和列数的图像。我想计算旋转后新图像的限制。 这是我的代码:

       BufferedImage myImage = ImageIO.read( new File( "D:\\Users...jpg" ) );
        xmaxOrigine = myImage.getWidth() - 1;
        ymaxOrigine = myImage.getHeight() - 1;
        angle = 12;

        angleRadian = Math.toRadians( angle );
        cos = Math.cos( angleRadian );
        sin = Math.sin( angleRadian );

        p1X = (int) ( ( xmaxOrigine * cos ) - ( ymaxOrigine * sin ) );
        p1Y = (int) ( ( xmaxOrigine * sin ) + ( ymaxOrigine * cos ) );

        xmin_f = xmin_f < p1X ? xmin_f : p1X;
        xmax_f = xmax_f < p1X ? p1X : xmax_f;
        ymin_f = ymin_f < p1Y ? ymin_f : p1Y;
        ymax_f = ymax_f < p1Y ? p1Y : ymax_f;

        p2X = (int) ( ( 0  * cos ) - ( ymaxOrigine * sin ) );
        p2Y = (int) ( ( 0 * sin ) + ( ymaxOrigine * cos ) );

        xmin_f = xmin_f < p2X ? xmin_f : p2X;
        xmax_f = xmax_f < p2X ? p2X : xmax_f;
        ymin_f = ymin_f < p2Y ? ymin_f : p2Y;
        ymax_f = ymax_f < p2Y ? p2Y : ymax_f;

        p3X = (int) ( ( xmaxOrigine * cos ) - ( 0 * sin ) );
        p3Y = (int) ( ( xmaxOrigine * sin ) + ( 0 * cos ) );

        xmin_f = xmin_f < p3X ? xmin_f : p3X;
        xmax_f = xmax_f < p3X ? p3X : xmax_f;
        ymin_f = ymin_f < p3Y ? ymin_f : p3Y;
        ymax_f = ymax_f < p3Y ? p3Y : ymax_f;

        p4X = 0;
        p4Y = 0;

        xmin_f = xmin_f < p4X ? xmin_f : p4X;
        xmax_f = xmax_f < p4X ? p4X : xmax_f;
        ymin_f = ymin_f < p4Y ? ymin_f : p4Y;
        ymax_f = ymax_f < p4Y ? p4Y : ymax_f;

        widthFinal = xmax_f - xmin_f;
        heightFinal = ymax_f - ymin_f;

如您所见,我查找每个点的 xmin、xmax、ymin、ymax。如果可能的话,我想做一次这个操作。

感谢您的帮助

【问题讨论】:

  • 您是否遇到了代码无法正常工作的问题?如果您想查看您的代码或提出改进建议,您应该将其发布到 CodeReview 而不是此处。
  • 您的代码得到了加分,因为它既美观又整洁。当它已经像这样组织时,很容易简化代码。一个例子:你应该使用Math.max()Math.min() 来代替三元运算符。大多数代码似乎相当于找到一组整数的最大值或最小值,所以编写一个函数maxOfAll(int... is) 并调用它。在 Java 8 中,IntStream 将为您执行此操作。
  • 这似乎是一个好主意,但我的项目是在 Java 1.7 中......而且我是一个完全的 java 初学者,你知道更开发的功能吗? @MarkoTopolnik
  • 没问题,按照Math.max()自己实现maxOfAll()。只需稍加思考即可。
  • 好吧其实 Math.max() 似乎是我需要的,但很遗憾它只能接受两个变量。我将尝试制作一个可以接受 10 个变量的函数,但对我来说这似乎很复杂@MarkoTopolnik

标签: java rotation bufferedimage trigonometry


【解决方案1】:

我做了类似的东西:

public int maxOfAll(int a, int b, int c, int d) {
    //Look for the maximum of 4 variable
    int temp1max = Math.max( a, b );
    int temp2max = Math.max( temp1max, c );
    int temp3 = Math.max( temp2max, d );
    return temp3;
}

public int minOfAll (int a, int b, int c, int d) {
    //Look for the minimum of 4 variable
    int temp1 = Math.min( a, b );
    int temp2 = Math.min( temp1, c );
    int temp3 = Math.min( temp2, d );
    return temp3;
}

你同意吗?

【讨论】:

  • 请注意,使用答案进行讨论是不合适的。但是,作为回应:您已经为固定数量的参数实现了函数,并且基本上您已经“展开”了通常使用的循环。您应该尝试找到可以使用事先未知大小的int[] 的解决方案。签名maxOfAll(int... ints) 会给你这个数组。
【解决方案2】:

如果我正确理解您的代码并提出问题,您希望在旋转后找到图像的边界。如果这不是一个任务,你应该自己实现它,你可能应该只使用 AffineTransformOp.getBounds2D(BufferedImage) 方法,它正是为此目的而制作的:

// Read the image and set angle (as before)
BufferedImage myImage = ImageIO.read(...));
double angle = 12;

// Create AffineTransformOp to do the calculation
AffineTransform rotation = AffineTransform.getRotateInstance(angle);
AffineTransformOp op = new AffineTransformOp(rotation, null);

Rectangle bounds = op.getBounds2D(myImage).getBounds(); // Correctly rounded bounds

// You can now use bounds.x, bounds.y, bounds.width and bounds.height as you like.
// Example:

widthFinal = bounds.width;
heightFinal = bounds.height;

【讨论】: