2013-11-28 16 views
6

के साथ छवि घूर्णन करने के लिए मुझे Airplane नामक कक्षा मिली है। इस कक्षा के अंदर मुझे परिवर्तनीय img मिला है जो BufferedImage प्रकार है।AffineTransform

@Override 
public void paintComponent(Graphics g) { 
    Graphics2D g2d = (Graphics2D) g; 
    g2d.drawImage(mapa, 0, 0, getWidth(), getHeight(), null); 
    drawAirplanes(g2d); 
} 

समारोह इस तरह drawAirplanes() देखो:

private void drawAirplane(Graphics2D g){ 
    for(Samolot i: s){ 
     i.rotateAirplane(); 
     g.drawImage(i.getImg(),i.getX(),i.getY(),(int)i.getDim().getWidth(),(int)i.getDim().getHeight(), null); 
    } 
} 

यह बस) 1 की जरूरत है हवाई जहाज (हवाई जहाज ऑब्जेक्ट के अंदर BufferedImage बारी बारी से) 2) आकर्षित किस क्लास WorldMap अधिक मैं मिल गया है जो समारोह paintComponent(Graphics g) ओवरराइड करता है है उसे।

मेरे Airplane.rotateAirplane() फ़ंक्शन इस तरह दिखता है:

public void rotateSamolot() { 
    AffineTransform tx = new AffineTransform(); 

    tx.translate(10,10); //10, 10 is height and width of img divide by 2 
    tx.rotate(Math.PI/2); 
    tx.translate(-10,-10); 

    AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR); 

    BufferedImage newImage =new BufferedImage(20, 20, img.getType()); //20, 20 is a height and width of img ofc 
    op.filter(img, newImage); 

     this.img = newImage; 
} 

ओएफसी जब मेरे कार्यक्रम चलाने im केवल mapa वस्तु ली गई है। जब im इस लेन को हटाने

this.img = newImage;

मैं अपने हवाई जहाज भी नहीं बल्कि घुमाया ओएफसी मिला है।

+0

मैं सुनिश्चित नहीं हूं आप AffineTransform का अनुवाद करना चाहते हैं, इसके बजाय, आपको घूर्णन विधि के साथ घूर्णन बिंदुओं की आपूर्ति करना चाहिए, जो आम तौर पर केंद्र बिंदु है, लेकिन यह आपके ऊपर है। मैं रोटेशन के परिणाम को वापस मास्टर छवि पर भी असाइन नहीं करता हूं अन्यथा आप घूर्णन को जोड़ते हैं .... – MadProgrammer

+1

मैं मूल रूप से क्या सोचता हूं "सोचता है", क्या आपकी छवि उपलब्ध स्थान के "सीमाओं से बाहर" घुमाया जा रहा है ... – MadProgrammer

+1

आप [इस उदाहरण] पर एक नज़र डाल सकते हैं (http://stackoverflow.com/questions/15779877/rotate-bufferedimage-inside-jpanel/15780090#15780090) – MadProgrammer

उत्तर

12

बड़ी समस्या (जो मैं देख सकता हूं) Graphics संदर्भ का अनुवाद है जो रोटेशन की स्थिति को ऑफसेट कर देता है।

मैं "सोचता हूं" डिफ़ॉल्ट रूप से रोटेशन Graphics संदर्भ के शीर्ष/बाएं कोने पर होता है (जहां यह 0x0 स्थिति है, जिसे आपने किसी अन्य चीज़ में अनुवादित किया है), इससे छवि को घुमाया जा सकता है फ्रेम (या देखने योग्य क्षेत्र)

आपको एक "एंकर" बिंदु प्रदान करना चाहिए जहां घूर्णन होता है, आमतौर पर, केंद्र मेरी निजी वरीयता है।

निम्नलिखित उदाहरण में केवल एक मास्टर छवि है (आकार की बाधाओं के कारण मुझे इसे स्केल करना था, लेकिन आपको इसकी आवश्यकता नहीं हो सकती है)। इसके बाद मैं इसका उपयोग "घुमावदार" उदाहरण उत्पन्न करने के लिए करता हूं जो छवि को अंदर फिट करने की अनुमति देने के लिए आकार दिया जाता है। यह ट्रिगर के साथ बहुत मजेदार है - मैंने कहीं से कोड चुरा लिया है, इसलिए उस डेवलपर को श्रेय दें।

उदाहरण आपको किसी भी स्थान पर क्लिक करने की अनुमति देता है और यह रोटेशन पिवट बदल देगा, ताकि आप देख सकें कि क्या हो रहा है। डिफ़ॉल्ट स्थिति फलक का केंद्र है ...

Spinning

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
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.JSlider; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

public class SampleRotation { 

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

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

       final RotationPane rotationPane = new RotationPane(); 
       final JSlider slider = new JSlider(0, 100); 
       slider.addChangeListener(new ChangeListener() { 
        @Override 
        public void stateChanged(ChangeEvent e) { 
         double angle = 720d * (slider.getValue()/100d); 
         rotationPane.setAngle(angle); 
        } 
       }); 
       slider.setValue(0); 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(rotationPane); 
       frame.add(slider, BorderLayout.SOUTH); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class RotationPane extends JPanel { 

     private BufferedImage img; 
     private BufferedImage rotated; 
     private double angle; 
     private Point clickPoint; 

     public RotationPane() { 
      try { 
       img = ImageIO.read(new File("/Users/swhitehead/Dropbox/MegaTokyo/issue459.jpg")); 
       BufferedImage scaled = new BufferedImage(img.getWidth()/2, img.getHeight()/2, BufferedImage.TYPE_INT_ARGB); 
       Graphics2D g2d = scaled.createGraphics(); 
       g2d.setTransform(AffineTransform.getScaleInstance(0.5d, 0.5d)); 
       g2d.drawImage(img, 0, 0, this); 
       g2d.dispose(); 
       img = scaled; 
       setAngle(0d); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 

      addMouseListener(new MouseAdapter() { 

       @Override 
       public void mouseClicked(MouseEvent e) { 
        clickPoint = e.getPoint(); 
        repaint(); 
       } 

      }); 

     } 

     public void setAngle(double angle) { 
      this.angle = angle; 

      double rads = Math.toRadians(getAngle()); 
      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); 

      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 = clickPoint == null ? w/2 : clickPoint.x; 
      int y = clickPoint == null ? h/2 : clickPoint.y; 

      at.rotate(Math.toRadians(getAngle()), 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(); 

      repaint(); 
     } 

     public double getAngle() { 
      return angle; 
     } 

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

     @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.setColor(Color.RED); 

       x = clickPoint == null ? getWidth()/2 : clickPoint.x; 
       y = clickPoint == null ? getHeight()/ 2 : clickPoint.y; 

       x -= 5; 
       y -= 5; 

       g2d.drawOval(x, y, 10, 10); 
       g2d.dispose(); 
      } 
     }   
    }  
} 
0

यह वही मेरे लिए (थोड़े यहाँ से कॉपी करने और वहाँ) काम किया है:

public BufferedImage rotateImag (BufferedImage imag, int n) { //n rotation in gradians 

     double rotationRequired = Math.toRadians (n); 
     double locationX = imag.getWidth()/2; 
     double locationY = imag.getHeight()/2; 
     AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired, locationX, locationY); 
     AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);   
     BufferedImage newImage =new BufferedImage(imag.getWidth(), imag.getHeight(), imag.getType()); //20, 20 is a height and width of imag ofc 
     op.filter(imag, newImage); 

      //this.img = newImage; 
     return(newImage); 
    } 
संबंधित मुद्दे