2011-04-13 73 views
14

我正在嘗試開發某種使用Java的繪畫。將JPanel圖形導出爲.png或.gif或.jpg

我有一個位於JPanel內部的JComponent。

我已經可以將線條和矩形繪製到該JComponent中。

現在,我該如何將圖形導出爲圖像(png,gif,jpg)?

我嘗試這樣做:

BufferedImage b = new BufferedImage(1700,1100,BufferedImage.TYPE_INT_RGB); 
this.print(getGraphics()); 
try{ImageIO.write(b,"png",new File("test.png"));}catch (Exception e) {} 

但是,只有創建一個.png文件全黑。

幫助!!!

RESOLVED !!!

BufferedImage bi = new BufferedImage(this.getSize().width, this.getSize().height, BufferedImage.TYPE_INT_ARGB); 
Graphics g = bi.createGraphics(); 
this.paint(g); //this == JComponent 
g.dispose(); 
try{ImageIO.write(bi,"png",new File("test.png"));}catch (Exception e) {} 
+5

你應該接受泰迪爾的答案。 – Dathan 2012-09-05 00:34:57

+0

所有對'paint'的調用都起作用,Java的API說*應用程序不應該直接調用paint,而應該使用repaint方法來調度組件進行重繪。*問題是很難知道什麼時候更新圖形完成後,確實可以保存正確的BufferedImage。我的一些測試顯示,您可以使用此技術將部分渲染的BufferedImage另存爲PNG。 – Fuhrmanator 2013-07-30 17:33:38

回答

8

首先,print()是不正確的方法。 我猜應該工作(還沒有測試過)是: 獲取BufferedImage的圖形(b.createGraphics())並將該圖形對象用於paint()您的面板/組件。

(例如yourPanel.paint(b.createGraphics());

-3

這是一個演示:

import javax.imageio.ImageIO; 
import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.util.ArrayList; 
import java.util.List; 

@SuppressWarnings("serial") 
public class DrawGraph extends JPanel { 
    private static final int PREF_W = 1000; 
    private static final int PREF_H = 800; 
    private static final int BORDER_GAP = 25; 
    private static final int PADDING = 25; 
    private static final Color GRAPH_COLOR = Color.green; 
    private static final Color GRAPH_POINT_COLOR = new Color(100, 100, 100, 180); 
    private static final Color GRID_COLOR = new Color(200, 200, 200, 200); 
    private static final Stroke GRAPH_STROKE = new BasicStroke(3f); 
    private static final int GRAPH_POINT_WIDTH = 4; 
    private static final int Y_HATCH_CNT = 10; 
    private List<Double> scores; 

    public DrawGraph(List<Double> scores2) { 
     this.scores = scores2; 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D)g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

     double xScale = ((double) getWidth() - (2 * BORDER_GAP)-PADDING)/(scores.size() - 1); 
     double yScale = ((double) getHeight() - (2 * BORDER_GAP)-PADDING)/(getMaxScore() - getMinScore()); 

     List<Point> graphPoints = new ArrayList<Point>(); 
     for (int i = 0; i < scores.size(); i++) { 
      int x1 = (int) (i * xScale + BORDER_GAP + PADDING); 
      int y1 = (int) ((getMaxScore() - scores.get(i)) * yScale + BORDER_GAP); 
      graphPoints.add(new Point(x1, y1)); 
     } 

     g2.setColor(Color.WHITE); 
     g2.fillRect(BORDER_GAP + PADDING, BORDER_GAP, getWidth() - (2 * BORDER_GAP) - PADDING, getHeight() - 2 * BORDER_GAP - PADDING); 
     g2.setColor(Color.BLACK); 

     g2.drawLine(BORDER_GAP + PADDING, getHeight() - BORDER_GAP - PADDING, BORDER_GAP + PADDING, BORDER_GAP); 
     g2.drawLine(BORDER_GAP + PADDING, getHeight() - BORDER_GAP - PADDING, getWidth() - BORDER_GAP, getHeight() - BORDER_GAP - PADDING); 

     for (int i = 0; i < Y_HATCH_CNT + 1; i++) { 
      int x0 = BORDER_GAP + PADDING; 
      int x1 = GRAPH_POINT_WIDTH + BORDER_GAP + PADDING; 
      int y0 = getHeight() - ((i * (getHeight() - BORDER_GAP * 2 - PADDING))/Y_HATCH_CNT + BORDER_GAP + PADDING); 
      int y1 = y0; 
      if (scores.size() > 0) { 
       g2.setColor(GRID_COLOR); 
       g2.drawLine(BORDER_GAP + PADDING + 1 + GRAPH_POINT_WIDTH, y0, getWidth() - BORDER_GAP, y1); 
       g2.setColor(Color.BLACK); 
       String yLabel = ((int) ((getMinScore() + (getMaxScore() - getMinScore()) * ((i * 1.0)/Y_HATCH_CNT)) * 100))/100.0 + ""; 
       FontMetrics metrics = g2.getFontMetrics(); 
       int labelWidth = metrics.stringWidth(yLabel); 
       g2.drawString(yLabel, x0 - labelWidth - 5, y0 + (metrics.getHeight()/2) - 3); 
      } 
      g2.drawLine(x0, y0, x1, y1); 
     } 

     for (int i = 0; i < scores.size(); i++) { 
      if (scores.size() > 1) { 
       int x0 = i * (getWidth() - BORDER_GAP * 2 - PADDING)/(scores.size() - 1) + BORDER_GAP + PADDING; 
       int x1 = x0; 
       int y0 = getHeight() - BORDER_GAP - PADDING; 
       int y1 = y0 - GRAPH_POINT_WIDTH; 
       if ((i % ((int) ((scores.size()/20.0)) + 1)) == 0) { 
        g2.setColor(GRID_COLOR); 
        g2.drawLine(x0, getHeight() - BORDER_GAP - PADDING - 1 - GRAPH_POINT_WIDTH, x1, BORDER_GAP); 
        g2.setColor(Color.BLACK); 
        String xLabel = i + ""; 
        FontMetrics metrics = g2.getFontMetrics(); 
        int labelWidth = metrics.stringWidth(xLabel); 
        g2.drawString(xLabel, x0 - labelWidth/2, y0 + metrics.getHeight() + 3); 
       } 
       g2.drawLine(x0, y0, x1, y1); 
      } 
     } 

     Stroke oldStroke = g2.getStroke(); 
     g2.setColor(GRAPH_COLOR); 
     g2.setStroke(GRAPH_STROKE); 
     for (int i = 0; i < graphPoints.size() - 1; i++) { 
      int x1 = graphPoints.get(i).x; 
      int y1 = graphPoints.get(i).y; 
      int x2 = graphPoints.get(i + 1).x; 
      int y2 = graphPoints.get(i + 1).y; 
      g2.drawLine(x1, y1, x2, y2); 
     } 

     g2.setStroke(oldStroke); 
     g2.setColor(GRAPH_POINT_COLOR); 
     for (int i = 0; i < graphPoints.size(); i++) { 
      int x = graphPoints.get(i).x - GRAPH_POINT_WIDTH/2; 
      int y = graphPoints.get(i).y - GRAPH_POINT_WIDTH/2;; 
      int ovalW = GRAPH_POINT_WIDTH; 
      int ovalH = GRAPH_POINT_WIDTH; 
      g2.fillOval(x, y, ovalW, ovalH); 
     } 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private double getMinScore() { 
     double minScore = Double.MAX_VALUE; 
     for (Double score : scores) { 
      minScore = Math.min(minScore, score); 
     } 
     return minScore; 
    } 

    private double getMaxScore() { 
     double maxScore = Double.MIN_VALUE; 
     for (Double score : scores) { 
      maxScore = Math.max(maxScore, score); 
     } 
     return maxScore; 
    } 

    public static void createAndShowGui(ArrayList<Double> scores, String s) { 
     DrawGraph mainPanel = new DrawGraph(scores); 

     JFrame frame = new JFrame(s); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.getContentPane().add(new JButton(new AbstractAction("Save Image") { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       mainPanel.saveImage(new File("graph.png")); 
      } 
     }),BorderLayout.SOUTH); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public void saveImage(File file){ 
     BufferedImage bi = new BufferedImage(this.getSize().width, this.getSize().height, BufferedImage.TYPE_INT_ARGB); 
     Graphics g = bi.createGraphics(); 
     this.paint(g); 
     g.dispose(); 
     try{ 
      ImageIO.write(bi,"png",file); 
     }catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String args[]) { 
     final ArrayList<Double> inputValues = new ArrayList<Double>(); 
     inputValues.add(1d); 
     inputValues.add(2d); 
     // Read input values from text document and store in ArrayList 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       DrawGraph.createAndShowGui(inputValues, "MyGraphTitle"); 
      } 
     }); 
    } 
} 

可以都由你自己改變它。

+0

這看起來像這個[問題](http://stackoverflow.com/q/39490009/230513)中代碼的幾乎逐字拷貝。 – trashgod 2016-09-14 14:21:29