2012-06-19 8 views
5

Tôi đang viết một chương trình mà tôi vẽ trên JPanel. Làm thế nào để tôi nhận được Image của số JPanel được vẽ trên đó? Tôi đã thử mã này nhưng tất cả những gì tôi nhận được là một hình ảnh trống với màu nền của JPanel. BufferedImage không chứa nội dung được vẽ trên bảng điều khiển của tôi.Java - Nhận một hình ảnh của một JPanel

private BufferedImage createImage(JPanel panel) {  
     int w = panel.getWidth(); 
     int h = panel.getHeight(); 
     BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
     Graphics2D g = bi.createGraphics(); 
     panel.paint(g); 
     return bi; 
    } 

Tôi đang làm gì sai?

+0

suy nghĩ dáng như thế nào bạn vẽ hình ảnh của bạn. Bạn có sử dụng graphics.drawImage không? Nếu có, đối số ImageObserver là gì? –

Trả lời

2

Dưới đây là một SSCCE minh họa rằng nó hoạt động. Sai lầm phổ biến là vượt qua null làm phương thức ImageObserver của phương thức drawImage vì việc tải hình ảnh không đồng bộ.

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 

import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class TestPrint { 

    protected static void initUI() throws MalformedURLException { 
     final ImageIcon image = new ImageIcon(new URL("http://www.travelblog.org/Wallpaper/pix/tb_fiji_sunset_wallpaper.jpg")); 
     JPanel panel = new JPanel() { 
      @Override 
      protected void paintComponent(java.awt.Graphics g) { 
       super.paintComponent(g); 
       g.drawImage(image.getImage(), 0, 0, this); 
      }; 
     }; 
     panel.setPreferredSize(new Dimension(image.getIconWidth(), image.getIconHeight())); 
     panel.setSize(panel.getPreferredSize()); 
     BufferedImage bi = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB); 
     Graphics g = bi.createGraphics(); 
     panel.print(g); 
     g.dispose(); 
     try { 
      ImageIO.write(bi, "png", new File("test.png")); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        initUI(); 
       } catch (MalformedURLException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 
} 
+0

đã dùng thử, không hoạt động. –

+2

@sijoune Hãy thử mã tôi đã đăng ở trên và thấy sự khác biệt với mã của bạn để phát hiện sự cố của bạn. –

2

Mã của bạn hoạt động cho tôi.

Đây là một ví dụ đơn giản. Thay đổi kích thước khung hình để xem kích thước của bảng điều khiển thay đổi và hình ảnh di chuyển xung quanh.

public static void main(String[] args) { 
    JFrame frame = new JFrame("Test"); 
    JPanel panel = new JPanel(); 
    panel.setBackground(Color.BLUE); 
    JLabel label = new JLabel("Image"); 
    label.setForeground(Color.RED); 
    panel.add(label); 
    frame.add(panel, BorderLayout.NORTH); 
    frame.pack(); 
    JLabel image = new JLabel(new ImageIcon(createImage(panel))); 
    frame.add(image, BorderLayout.SOUTH); 
    frame.pack(); 
    label.setText("Original");  
    frame.setVisible(true); 
} 

private static BufferedImage createImage(JPanel panel) { 
    int w = panel.getWidth(); 
    int h = panel.getHeight(); 
    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g = bi.createGraphics(); 
    panel.paint(g); 
    return bi; 
} 

Vì vậy, vấn đề của bạn phải ở nơi khác. Hãy chắc chắn rằng bảng điều khiển của bạn có kích thước tích cực tại điểm mà bạn tạo ra một hình ảnh của nó.

2

Đây là phương pháp ví dụ nhanh mà bạn có thể thêm vào bất kỳ ứng dụng Java 2/JDK 1.2 nào của mình. Chỉ cần chuyển thành phần bạn muốn chụp nhanh và tên tệp bạn muốn lưu vào đó.

public void saveComponentAsJPEG(Component myComponent, String filename) { 
    Dimension size = myComponent.getSize(); 
    BufferedImage myImage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g2 = myImage.createGraphics(); 
    myComponent.paint(g2); 
    try { 
     OutputStream out = new FileOutputStream(filename); 
     JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 
     encoder.encode(myImage); 
     out.close(); 
    } catch (Exception e) { 
     System.out.println(e); 
    } 
} 

Phương pháp này rất linh hoạt. Nó có thể được sử dụng để chụp nhanh các thành phần ứng dụng Java khác nhau. Tuy nhiên, xin hãy cảnh báo rằng bạn sử dụng com.sun.image.codec.jpeg với một số rủi ro đối với tính di động của mã của bạn.

EDIT: Tôi đã thử nghiệm mã để đảm bảo và tất cả có vẻ tốt đẹp:

import com.sun.image.codec.jpeg.JPEGCodec; 
import com.sun.image.codec.jpeg.JPEGImageEncoder; 
import java.awt.*; 
import java.awt.geom.Ellipse2D; 
import java.awt.image.BufferedImage; 
import java.io.FileOutputStream; 
import java.io.OutputStream; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class ScreenCapture extends JFrame { 

    public ScreenCapture() { 
     createAndShowUI(); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       ScreenCapture screenCapture = new ScreenCapture(); 
      } 
     }); 
    } 

    private void createAndShowUI() { 
     setTitle("Test Screen Capture"); 
     setSize(300, 300); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setLocationRelativeTo(null); 
     getContentPane().add(new DrawingPanel()); 
     setVisible(true); 
     saveComponentAsJPEG(this, "C:/test.jpg"); 

    } 

    public void saveComponentAsJPEG(Component myComponent, String filename) { 
     Dimension size = myComponent.getSize(); 
     BufferedImage myImage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB); 
     Graphics2D g2 = myImage.createGraphics(); 
     myComponent.paint(g2); 
     try { 
      OutputStream out = new FileOutputStream(filename); 
      JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 
      encoder.encode(myImage); 
      out.close(); 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
    } 

    class DrawingPanel extends JPanel { 

     public DrawingPanel() { 
      setDoubleBuffered(true); 
     } 

     @Override 
     public void paintComponent(Graphics grphcs) { 
      super.paintComponents(grphcs); 
      Graphics2D g2d = (Graphics2D) grphcs; 

      RenderingHints rhints = g2d.getRenderingHints(); 
      boolean antialiasOn = rhints.containsValue(RenderingHints.VALUE_ANTIALIAS_ON); 

      if (!antialiasOn) { 
       g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      } 

      Shape circle = new Ellipse2D.Float(100.0f, 100.0f, 100.0f, 100.0f); 

      g2d.setColor(Color.RED); 
      g2d.draw(circle); 
      g2d.fill(circle); 
     } 
    } 
} 
+0

Tôi đã thử nó và điều tương tự cũng xảy ra. Tôi không hiểu. Tôi phải làm điều gì khác sai, nhưng tôi không thể tìm thấy nó. –

+0

kiểm tra chỉnh sửa của tôi, và sau đó có thể đăng các mã có thể được đưa ra vấn đề, tôi không thấy như thế nào, bởi vì như bạn có thể thấy một khi bạn vượt qua một thành phần và tên tập tin vào phương pháp nó làm phần còn lại? –