2017-10-28 74 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”);'加载它。所有这些你在你的项目中做过,所以你不应该对这段代码有任何问题。 –