2016-06-10 133 views
0

我想旋轉java中的緩衝圖像。這裏是我使用的代碼:在Java中旋轉緩衝圖像

public static BufferedImage rotate(BufferedImage bimg, double angle){ 
    int w = bimg.getWidth();  
    int h = bimg.getHeight(); 
    Graphics2D graphic = bimg.createGraphics(); 
    graphic.rotate(Math.toRadians(angle), w/2, h/2); 
    graphic.drawImage(bimg, null, 0, 0); 
    graphic.dispose(); 
    return bimg; 
} 

我已經看過這個話題無數堆棧溢出的問題和答案,並沒有能夠找出爲什麼圖像被切碎,事情是這樣的,當我嘗試旋轉它。這裏是在加載圖像的例子: loaded image

我點擊旋轉按鈕,調用帶緩衝的圖像上面的功能和對角90.0後: chopped up image

有人可以幫助我瞭解什麼是發生和如何解決它?

謝謝!

+0

旋轉圖形?請列出所有提示的答案 - 除非你給我這樣一個可信的來源 – gpasch

+0

對不起,我不明白你在找什麼。你想鏈接到我嘗試過的stackoverflow解決方案嗎? – Zugor

回答

-1

您必須考慮輸出的大小調整和新的寬度和高度。參見:https://stackoverflow.com/a/4787898/5420880

+0

我不確定如何行GraphicsConfiguration gc = getDefaultConfiguration();作品。我搜索了它,看到你需要GraphicsEnvironment然後GraphicsDevice。不知道如何使用它。我在建議的鏈接中複製了該功能,並導致錯誤。 – Zugor

4

一如既往,互聯網來救援。所以,這是一些代碼,我從其他資源/後/博客步履蹣跚一起將返回其大小的新形象,因此將包含旋轉圖像

public BufferedImage rotateImageByDegrees(BufferedImage img, double angle) { 

      double rads = Math.toRadians(angle); 
      double sin = Math.abs(Math.sin(rads)), cos = Math.abs(Math.cos(rads)); 
      int w = img.getWidth(); 
      int h = img.getHeight(); 
      int newWidth = (int) Math.floor(w * cos + h * sin); 
      int newHeight = (int) Math.floor(h * cos + w * sin); 

      BufferedImage rotated = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB); 
      Graphics2D g2d = rotated.createGraphics(); 
      AffineTransform at = new AffineTransform(); 
      at.translate((newWidth - w)/2, (newHeight - h)/2); 

      int x = w/2; 
      int y = h/2; 

      at.rotate(rads, x, y); 
      g2d.setTransform(at); 
      g2d.drawImage(img, 0, 0, this); 
      g2d.setColor(Color.RED); 
      g2d.drawRect(0, 0, newWidth - 1, newHeight - 1); 
      g2d.dispose(); 

      return rotated; 
     } 

更新

因此,使用這PNG:

Image

而這個代碼...

package javaapplication1.pkg040; 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.AffineTransform; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private BufferedImage master; 
     private BufferedImage rotated; 

     public TestPane() { 
      try { 
       master = ImageIO.read(new File("/Volumes/Disk02/Dropbox/MegaTokyo/Miho_Small.png")); 
       rotated = rotateImageByDegrees(master, 0.0); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 

      Timer timer = new Timer(40, new ActionListener() { 
       private double angle = 0; 
       private double delta = 1.0; 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        angle += delta; 
        rotated = rotateImageByDegrees(master, angle); 
        repaint(); 
       } 
      }); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return master == null 
         ? new Dimension(200, 200) 
         : new Dimension(master.getWidth(), master.getHeight()); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      if (rotated != null) { 
       Graphics2D g2d = (Graphics2D) g.create(); 
       int x = (getWidth() - rotated.getWidth())/2; 
       int y = (getHeight() - rotated.getHeight())/2; 
       g2d.drawImage(rotated, x, y, this); 
       g2d.dispose(); 
      } 
     } 

     public BufferedImage rotateImageByDegrees(BufferedImage img, double angle) { 

      double rads = Math.toRadians(angle); 
      double sin = Math.abs(Math.sin(rads)), cos = Math.abs(Math.cos(rads)); 
      int w = img.getWidth(); 
      int h = img.getHeight(); 
      int newWidth = (int) Math.floor(w * cos + h * sin); 
      int newHeight = (int) Math.floor(h * cos + w * sin); 

      BufferedImage rotated = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB); 
      Graphics2D g2d = rotated.createGraphics(); 
      AffineTransform at = new AffineTransform(); 
      at.translate((newWidth - w)/2, (newHeight - h)/2); 

      int x = w/2; 
      int y = h/2; 

      at.rotate(rads, x, y); 
      g2d.setTransform(at); 
      g2d.drawImage(img, 0, 0, this); 
      g2d.dispose(); 

      return rotated; 
     } 
    } 

} 

我可以生成類似...

Rotating

+0

任何人都希望在投票的理由上給我啓發嗎?它不以什麼方式回答這個問題?由於我看到你沒有選擇投票表決任何其他答案,我只能假設你發現這個問題有什麼問題,所以我很想知道如何改進以更好地幫助操作。 – MadProgrammer

+0

感謝它的代碼工作得很好。我有一個問題,在加載到BufferedImage之前,圖像的格式是否重要?我問,因爲當我加載JPEG的旋轉工作正常,但是當我加載像PNG的其他東西程序凍結,我不得​​不停止進程。 – Zugor

+0

不是我所知道的,我傾向於更喜歡PNG,因爲它們支持alpha通道 – MadProgrammer