2012-10-20 34 views
4

我有一個簡單的應用程序,允許用戶在畫布控件中繪製。無法將當前畫布數據轉換爲java中的圖像

現在,我想要的是將該畫布轉換爲圖像。所以這是我的代碼。

public void paint(Graphics g) 
{ 
    //super.paint(g); 
    Graphics2D draw = (Graphics2D) g; 
    if(this.is_beginning || this.to_save) 
    { 
     draw.setColor(Color.white); 
     draw.fillRect(0, 0, this.getWidth(), this.getHeight()); 
     this.is_beginning= false; 
    } 
    if(this.m_alzada) 
    { 
     draw.setColor(Color.red); 
     draw.drawLine(uX, uY, x, y); 

    } 
} 

這是我保存圖像的方法。

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {           
    int w = canvas1.getWidth(); 
    int h = canvas1.getHeight(); 
    int type = BufferedImage.TYPE_INT_BGR; 
    BufferedImage image = new BufferedImage(w,h,type); 
    Graphics2D g2 = image.createGraphics(); 
    canvas1.to_save = true; 
    canvas1.paint(g2); 
    try { 
     ImageIO.write(image, "png", new File("C:/Users/Uriel/Desktop/ejemplo.png")); 
    } catch (IOException ex) { 
     Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex); 
    } 

} 

所有這些結果在一個空白的形象,我知道paint方法是如何工作的,我意識到這是在那裏有我的問題是。但我怎麼能畫出用戶已經在繪製方法中繪製的所有東西?

對不起,因爲我的英語不好,我來自墨西哥。謝謝你的方式。

我想知道是否有任何事情可以像使用Canvas或HTML5一樣工作,並且您可以獲得帶有畫布中每個像素RGB信息的矩陣。是否有可能用JAVA中的畫布組件做到這一點?

+0

1)爲了更好地幫助更快,發佈[SSCCE](http://sscce.org/)。 2)*「請原諒我英語不好,我來自墨西哥。」*同上。我來自澳大利亞。 ;) –

+0

如果'!this.m_alzada'圖像將是白色的! –

+0

我會搜索abotu sscce,因爲網頁無法打開。那麼,this.m_alzada是一個布爾變量,它將被用於知道用戶是否希望在畫布上繪製,它總是如此,我要用按鈕來改變它的狀態,但首先我需要做這個工作。 –

回答

5

除了確保組件的尺寸正確外,還應使用JComponent#printJComponent#printAll方法。

這些都將禁止雙緩衝和過度出現一些其他本地同行的問題時,它期望打印到屏幕

修訂

從示例應用程序...

enter image description here

我能夠生產這個轉儲

​​

使用此代碼

Container pane = frame.getContentPane(); 
BufferedImage img = new BufferedImage(pane.getWidth(), pane.getHeight(), BufferedImage.TYPE_INT_RGB); 
Graphics2D g2d = img.createGraphics(); 
pane.printAll(g2d); 
g2d.dispose(); 
try { 
    ImageIO.write(img, "png", new File("save.png")); 
} catch (IOException ex) { 
    ex.printStackTrace(); 
} 

修訂

我不認爲你畫是你的問題的根源。它雖然不夠乾淨。

首先,您的「繪圖」表面從java.awt.Canvas延伸,並將其添加到JFrame,混合重量輕和重量輕的組件從來就不是一個好主意。

public class Dibujo extends Canvas ... 

你使用像JPanel

public class Dibujo extends JPanel ... 

東西永遠不要這樣做

public void paint(Graphics g) { 
    //super.paint(g); 

的更好,必須調用super.paint有在後面更回事,然後簡單地填充零件。一旦你開始使用類似JPanel之類的東西,你會想要替代paintComponent

你永遠只能繪製最後一條線段在你畫法...

if (this.m_alzada) { 
    draw.setColor(Color. 
    draw.drawLine(uX, uY, x, y); 
} 

這意味着當您試圖保存組件,你只會看到過最後一段。每次調用時,paint方法應該繪製所有線段。

在你mouseDragged方法,你這樣做......

this.paint(this.getGraphics()); 

沒有。您不負責更新重繪管理器的圖形。所有這一切基本上是在繪製到便箋式圖形上下文中,只要下一個重繪請求處理完畢,它將全部擦乾淨。

我想你需要通過Performing Custom Painting來了解一些基本概念。我還會通過Painting in AWT and Swing來了解如何在Java中使用繪畫。

修改代碼後,我能得到這個...

enter image description here

要保存這樣的...

enter image description here

package prueba_uno_graphics; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.Shape; 
import java.awt.event.*; 
import java.awt.geom.Path2D; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JPanel; 

/** 
* 
* @author Uriel 
*/ 
// Don't mix heavy and light weight components 
public class Dibujo extends JPanel implements ActionListener, MouseListener, MouseMotionListener { 

// ArrayList lineas = new ArrayList(); 
// boolean m_alzada = true, is_beginning = true, to_save = false; 
// int uX, uY, x, y; 

    private Path2D shape; 

    Dibujo() { 
     setBackground(Color.WHITE); 
     shape = new Path2D.Float(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D draw = (Graphics2D) g; 
//  if (this.is_beginning || this.to_save) { 
//   draw.setColor(Color.white); 
//   draw.fillRect(0, 0, this.getWidth(), this.getHeight()); 
//   this.is_beginning = false; 
//  } 
//  if (this.m_alzada) { 
//   draw.setColor(Color.red); 
//   draw.drawLine(uX, uY, x, y); 
// 
//  } 

     draw.setColor(Color.RED); 
     draw.draw(shape); 

    } 

// @Override 
// public void paint(Graphics g) { 
//  // ALWAYS call super.paint 
//  super.paint(g); 
//  Graphics2D draw = (Graphics2D) g; 
//  if (this.is_beginning || this.to_save) { 
//   draw.setColor(Color.white); 
//   draw.fillRect(0, 0, this.getWidth(), this.getHeight()); 
//   this.is_beginning = false; 
//  } 
//  if (this.m_alzada) { 
//   draw.setColor(Color.red); 
//   draw.drawLine(uX, uY, x, y); 
// 
//  } 
// } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
    } 

    @Override 
    public void mouseClicked(MouseEvent e) { 
    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
     //  this.uX = e.getX(); 
     //  this.uY = e.getY(); 
     Point point = e.getPoint(); 
     shape.moveTo(point.x, point.y); 

    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
    } 

    @Override 
    public void mouseEntered(MouseEvent e) { 
    } 

    @Override 
    public void mouseExited(MouseEvent e) { 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 
     //  this.x = e.getX(); 
     //  this.y = e.getY(); 
     // Don't do this! 
     //  this.paint(this.getGraphics()); 
     //  ArrayList ayuda = new ArrayList(); 
     //  ayuda.add(uX); 
     //  ayuda.add(uY); 
     //  ayuda.add(x); 
     //  ayuda.add(y); 
     //  this.lineas.add(ayuda); 
     //  uX = x; 
     //  uY = y; 
     Point point = e.getPoint(); 
     shape.lineTo(point.x, point.y); 
     repaint(); 

    } 

    @Override 
    public void mouseMoved(MouseEvent e) { 
    } 

} 
+0

我試過打印和結果是一樣的。我在想,當你打電話給油漆或打印方法時,它會涉及到打印方法,並且會在那裏說出它所說的內容。我認爲我不太清楚這是如何工作的。 –

+0

看看更新 – MadProgrammer

+0

有兩件事情在我身上跳出來,你使用'TYPE_INT_BGR'的圖像類型,雖然可能不是什麼大不了的事情,但它可能會讓你困擾,另一個是你正在處理圖形在寫圖像之前的上下文。這可能有助於「關閉」圖形並使其可以保存 – MadProgrammer