2017-10-28 64 views
1

我想從MySQL中檢索圖像,並使用Java Swing將其加載到JLabel如何從MySQL檢索圖像到Java Swing?

但我無法得到這項工作。

這裏是我下面的代碼和錯誤,我越來越:

try { 
    Class.forName("com.mysql.jdbc.Driver"); // MySQL database connection 
    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/image_db", "root", "root"); 
    PreparedStatement pst = conn.prepareStatement("Select * from image_tbl where id='"+jTextField1.getText()+"'"); 
    ResultSet rs = pst.executeQuery(); 

    byte b[] = null; 
    while(rs.next()) 
    { 
     b= rs.getBytes(2); 
    } 

    jLabel1.setIcon(new ImageIcon (Toolkit.getDefaultToolkit().createImage(b))); 
} catch (Exception e) { 
    JOptionPane.showMessageDialog(null, "Wrong Data Detected! Please provide correct data"); 
}  

異常發生的歷史:

sun.awt.image.ImageFormatException: JPEG datastream contains no image 
     at sun.awt.image.JPEGImageDecoder.readImage(Native Method) 
     at sun.awt.image.JPEGImageDecoder.produceImage(JPEGImageDecoder.java:141) 
     at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:269) 
     at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:205) 
     at sun.awt.image.ImageFetcher.run(ImageFetcher.java:169) 
    Premature end of JPEG file 
+0

您正在選擇表中的每一列。您應該選擇具有圖像字節的列。 – JJF

+0

恩,[有一種方法](https://stackoverflow.com/questions/29983710/displaying-images-from-mysql-database-on-a-single-column-of-jtable/29983992#29983992),[這裏有另一個](https://stackoverflow.com/questions/20752432/convert-bufferedinputstream-into-image/20753089#20753089),[和另一個](https://stackoverflow.com/questions/35069359/trying-to-retrieve -both-text-and-blob-from-mysql-to-jtable/35072936#35072936) – MadProgrammer

+0

首先,如上所述,您只是讀取所有結果以加載最後一張圖片;其次,我將驗證讀取的字節數與寫入的字節數相同,但由於我們不知道圖像是如何寫入的,我們不知道使用這種方法是否最好理念;第三,我會在'createImage'上使用'ImageIO',只是因爲它不涉及任何線程 – MadProgrammer

回答

0

這是一個MySQL的blob序列化的圖像(圖標)的一個簡單的例子。

create table t1(id integer primary key auto_increment,img longblob not null);

public class Database { 
    public Database() { 
    } 

    private Connection getConnection() throws SQLException { 
     return DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "toor"); 
    } 

    public boolean storeIcon(Icon icon) throws SQLException, IOException { 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     try(ObjectOutputStream os = new ObjectOutputStream(baos)) { 
      os.writeObject(icon); 
     } 

     try(Connection connection = getConnection()) { 
      String query = "insert into t1 (img) values (?)"; 

      try(PreparedStatement statement = connection.prepareStatement(query)) { 
       statement.setBlob(1, new ByteArrayInputStream(baos.toByteArray())); 
       return statement.executeUpdate() > 0; 
      } 
     } 
    } 

    public Icon loadIcon(long id) throws SQLException, IOException, ClassNotFoundException { 
     try(Connection connection = getConnection()) { 
      String query = "select img from t1 where id = ?"; 

      try(PreparedStatement statement = connection.prepareStatement(query)) { 
       statement.setLong(1, id); 

       try(ResultSet rs = statement.executeQuery()) { 
        if(rs.next()) { 
         Blob blob = rs.getBlob("img"); 

         try(ObjectInputStream is = new ObjectInputStream(blob.getBinaryStream())) { 
          return (Icon) is.readObject(); 
         } 
        } 

        return null; 
       } 
      } 
     } 
    } 
} 

這是一個測試應用程序。從數據庫中讀取圖像是在固定圖像ID等於1的情況下進行的,僅供演示。在真正的實現中,壓縮數據以節省空間是很好的。當然,提取記錄的圖像(物體)應該限制在絕對最小值。

public class MainFrame extends JFrame { 

    private JLabel imageLabel = new JLabel(); 

    private JButton loadImageFromFileButton = new JButton("Load image from file"); 
    private JButton storeImageIntoDBButton = new JButton("Store image into DB"); 
    private JButton loadImageFromDBButton = new JButton("Load image from DB"); 

    public MainFrame() throws HeadlessException { 
     super("JDBC Test"); 
     createGUI(); 
    } 

    private void createGUI() { 
     setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     setLayout(new BorderLayout(5, 20)); 

     imageLabel.setPreferredSize(new Dimension(200, 200)); 
     imageLabel.setHorizontalAlignment(JLabel.CENTER); 
     imageLabel.setVerticalAlignment(JLabel.CENTER); 

     loadImageFromFileButton.addActionListener(this::loadImageFromFile); 
     loadImageFromDBButton.addActionListener(this::loadImageFromDB); 
     storeImageIntoDBButton.addActionListener(this::storeImageIntoDB); 

     JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0)); 
     buttonsPanel.add(loadImageFromFileButton); 
     buttonsPanel.add(Box.createHorizontalStrut(25)); 
     buttonsPanel.add(loadImageFromDBButton); 
     buttonsPanel.add(Box.createHorizontalStrut(5)); 
     buttonsPanel.add(storeImageIntoDBButton); 

     add(imageLabel, BorderLayout.CENTER); 
     add(buttonsPanel, BorderLayout.PAGE_END); 

     pack(); 
     setLocationRelativeTo(null); 
    } 

    private void loadImageFromFile(ActionEvent event) { 
     JFileChooser chooser = new JFileChooser(); 
     if(chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { 
      ImageIcon imageIcon = new ImageIcon(chooser.getSelectedFile().getAbsolutePath()); 
      imageLabel.setIcon(imageIcon); 
     } 
    } 

    private void storeImageIntoDB(ActionEvent event) { 
     try { 
      Database db = new Database(); 
      db.storeIcon(imageLabel.getIcon()); 
     } 
     catch (SQLException | IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void loadImageFromDB(ActionEvent event) { 
     try { 
      Database db = new Database(); 
      Icon icon = db.loadIcon(1L); 
      imageLabel.setIcon(icon); 
     } 
     catch (SQLException | IOException | ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> new MainFrame().setVisible(true)); 
    } 
} 
+0

其獲取異常:未找到驅動程序應在哪裏添加驅動程序 –

+0

在應用程序的類路徑中,必須添加mysql驅動程序jar文件。如果您在4.2之前使用JDBC的版本,則必須使用'Class.forName(「com.mysql.jdbc.Driver」);'加載它。所有這些你在你的項目中做過,所以你不應該對這段代碼有任何問題。 –