【问题标题】:Black area using java 2D graphics rotation?黑色区域使用java 2D图形旋转?
【发布时间】:2013-11-18 11:18:15
【问题描述】:

我将首先展示错误的示例,然后我将解释如何,最后我会提出我的问题。

这是我要旋转的图片。

我多次将其旋转 90 度和 270 度,然后将它们组合成一个大的缓冲图像。

我用来旋转单个 bufferedImage 的代码是这样的:

public static BufferedImage rotate(BufferedImage img, int angle) {  
    int w = img.getWidth();  
    int h = img.getHeight();  

    BufferedImage dimg = new BufferedImage(w, h, img.getType());

    Graphics2D g = dimg.createGraphics();
    g.rotate(Math.toRadians(angle), w/2, h/2);  
    g.drawImage(img, null, 0, 0);  
    return dimg;  
}

旋转的结果看起来像这样。

之所以出现这些黑条,是因为在代码中您可以清楚地看到我创建了一个单独的缓冲图像,这将是最终图像。

它使用原始宽度和高度,因为图像旋转了高度和高度开关,所以我通过将 BufferedImage dimg = new BufferedImage(w, h, img.getType()); 更改为 BufferedImage dimg = new BufferedImage(h, w, img.getType()); 来弥补这一点。

我认为这将解决我的问题是合乎逻辑的。
但我错了,现在轮换的结果是这样的。

因此,从这一点开始,我不知道为什么要这样做。
我可能只是忽略了一件小事,或者这是一个常见错误,即使我找不到
任何发生这种情况的实例。

所以这是我的问题,为什么它会这样做?我该如何解决这个问题。

【问题讨论】:

  • 你的图片不是正方形的;你需要决定如何解决这个问题。
  • 我前一阵子修好了,不记得怎么弄的,所以没有答案。

标签: java swing lwjgl bufferedimage graphics2d


【解决方案1】:

图像不是正方形的。如果将其旋转 90°,则会创建一个需要填充的间隙。

解决方案:

  • 确保图片是方形的
  • “旋转”大小:当你旋转 90° 或 270° 时,你需要创建一个交换宽度和高度的目标图像(即 200x100 -> 100x200)
  • 裁剪图像。在你的情况下很好,因为缩放会使箭头看起来很糟糕,但它可能不在中心
  • 缩放图像。如果是 609x579,请将其缩小到 579x579(缩小通常看起来会更好一点)。
  • 找到边框颜色,旋转后用边框颜色填充空隙

【讨论】:

  • 问题是它需要独立于大小,或者更好地说它需要能够得到正确的结果,无论大小是正方形还是非正方形。主要原因是较大的最终图像中各个图像的大小是通过复杂的计算完成的,具体取决于用户信息的负载。如果我要裁剪或缩放图像,问题将是所述图像的位置不会位于相对于纸张的正确位置。这意味着我将不得不改变几件事。我想要的是当旋转正确而不是方形时。
  • 在这种情况下,您需要旋转图像,还要“旋转”最终图像的大小。 IE。当您旋转 90° 或 270° 时,您需要创建具有交换宽度和高度的目标图像。 (即 200x100 -> 100x200)
  • 第二个例子是交换宽高
  • 那么问题出在哪里?
【解决方案2】:

我想通了。

我一开始做的是旋转主机图像(dimg),
然后将原始图像绘制到它。
我也可以尝试将一个正方形放入一个圆圈中,而我之前的旋转实际上
根本没有意义。

所以我需要做的是首先创建主机,将图像绘制到主机,旋转
主机并将其作为最终图像返回。

public static BufferedImage rotate(BufferedImage img, int angle) {  
    int w = img.getWidth();  
    int h = img.getHeight();  

    BufferedImage dimg = new BufferedImage(w, h, img.getType());

    Graphics2D g = dimg.createGraphics();
    g.drawImage(img, null, 0, 0); //Draw before rotating
    g.rotate(Math.toRadians(angle), w/2, h/2); //Rotating after drawing
    return dimg;  
}

我希望这对其他人也有帮助

【讨论】:

    【解决方案3】:

    如果您想使用与第一个代码类似的代码 这可能会有所帮助(如果您删除 cmets 和调试行(例如绘制背景),它只有 translate((W-w)/2,(H-h)/2) 行)

    // do not forget to import static java.lang.Math.*
    public static BufferedImage rotate(BufferedImage img, int angle) {  
        int w = img.getWidth(null);  
        int h = img.getHeight(null);  
        double rad = toRadians(angle);
        double eps = 1e-3;
        int W=(int)(abs(cos(rad))*w+abs(sin(rad))*h-eps)+1;//W after rotation(calculated by using a little geometry ) 
        int H=(int)(abs(sin(rad))*w+abs(cos(rad))*h-eps)+1;//H after rotation
        //you may use max value ( diameter of the rectangle ) instead of dynamic value but in that case you must be careful of the black edges ( in this case red edges ) 
        // if 90 is not a divisor of angle then you can't fit a rectangle with that angle in another one so the red edges are inevitable 
        // but with calculated W and H this edges are minimum 
    
        BufferedImage dimg = new BufferedImage(W,H, BufferedImage.TYPE_INT_RGB);// you can change it to any type you want it's just a sample 
        Graphics2D g = dimg.createGraphics();
        g.setColor(Color.RED); // background color of red for displaying the red edges when image is not completely fit 
        g.fillRect(0, 0, W, H);
        int x=(W-w)/2;   
        int y=(H-h)/2;  
        g.translate(x, y); // moving dimg center to img center ( this was what first code lack in  ) 
        g.rotate(-rad, w/2, h/2);  // now rotating dimg around the center of img ( which is now same as center of dimg )
        // we rotate dimg by -rad and draw img normally , it's like rotating img by rad instead of dimg by -rad
        g.drawImage(img,null,0,0);  // and drawing
        return dimg;  
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-06
      • 1970-01-01
      • 2011-08-04
      • 1970-01-01
      • 2017-01-22
      • 2021-05-29
      相关资源
      最近更新 更多