Converti BufferedInputStream in immagine

Sto avendo problemi a trasformare il mio blob in un’immagine bufferizzata, così posso usarlo. Ricevo un blob (immagine jpg) dal mio database che ho caricato usando inputstream. Nel mio database è memorizzato come BufferedInputStream che noto. Ottengo il blob bene, è un mucchio di simboli strani e dice che è un jpg quindi l’immagine deve andare bene. Qualcuno può capire cosa sto facendo male? Forse lo sto convertendo in modo sbagliato? At image = ImageIO.read (new ByteArrayInputStream (data)); L’immagine restituisce null.

@GET @Path("{id}") @Produces("image/*") public Response post(@PathParam("id") String id) throws IOException { Connection con = connection(); Blob blob = getPhoto(con); BufferedImage image = null; byte[] data = null; int blobLength = 0; try { blobLength = (int) blob.length(); data = blob.getBytes(1, blobLength); image = ImageIO.read(new ByteArrayInputStream(data)); // ImageIO.write(image, "JPEG", new File("C:/Users/Nicolas/Desktop/image.jpg")); } catch (SQLException e2) { e2.printStackTrace(); } return Response.ok(image).build(); } 

Come scrivo al database

 public void postPhoto(Connection con, InputStream uploadedInputStream){ String mySQL = "INSERT INTO photos (photo) values (?)"; PreparedStatement pStmt = con.prepareStatement(mySQL); pStmt.setBlob(1, uploadedInputStream); pStmt.execute(); } 

Come invio il file al mio servlet

 var fileInput = document.getElementById('file'); var file = fileInput.files[0]; var formData = new FormData(); formData.append("file", file); var parameters="first="+firstName+"&last="+lastName+"&file="+file; xmlhttp.open("post","http://localhost:8080/restService/api/submitinfo",true); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.send(formData); 

Iniziare verificando che uploadInputStream sia un’immagine valida, è ansible scriverlo utilizzando ImageIO.write . È sempre ansible utilizzare ImageIO.read per leggere nuovamente l’immagine e reinserirla in un ByteArrayInputStream 😉

Ho fatto un rapido test usando il database H2.

Alcune cose che ho notato. Blob#length restituisce un valore long , mentre Blob#getBytes aspetta un int , questo potrebbe significare che stai troncando il stream di byte.

Inoltre, dalla documentazione di H2, sembrerebbe che il contenuto di Blob non sia tenuto in memoria, quindi uso invece getBinaryStream .

 import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.sql.Blob; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JScrollPane; public class TestImageDatbase { private Connection con; public static void main(String[] args) { new TestImageDatbase(); } public TestImageDatbase() { try { clearDatabase(); saveImage(); loadImage(); } catch (ClassNotFoundException | SQLException | IOException exp) { exp.printStackTrace(); } } protected Connection getConnection() throws ClassNotFoundException, SQLException { Class.forName("org.h2.Driver"); return DriverManager.getConnection("jdbc:h2:d:\\Image", "sa", ""); } protected void clearDatabase() throws IOException, ClassNotFoundException, SQLException { Connection con = null; PreparedStatement stmt = null; try { con = getConnection(); System.out.println("Cleaning database"); stmt = con.prepareStatement("delete from images"); int updated = stmt.executeUpdate(); System.out.println("Updated " + updated + " rows"); } finally { try { stmt.close(); } catch (Exception e) { } try { con.close(); } catch (Exception e) { } } } protected void saveImage() throws IOException, ClassNotFoundException, SQLException { Connection con = null; PreparedStatement stmt = null; ByteArrayOutputStream baos = null; ByteArrayInputStream bais = null; try { baos = new ByteArrayOutputStream(); File source = new File("/path/to/file"); System.out.println("Source size = " + source.length()); BufferedImage img = ImageIO.read(source); ImageIO.write(img, "png", baos); baos.close(); bais = new ByteArrayInputStream(baos.toByteArray()); con = getConnection(); stmt = con.prepareStatement("insert into images (image) values (?)"); stmt.setBinaryStream(1, bais); int updated = stmt.executeUpdate(); System.out.println("Updated " + updated + " rows"); } finally { try { bais.close(); } catch (Exception e) { } try { baos.close(); } catch (Exception e) { } try { stmt.close(); } catch (Exception e) { } try { con.close(); } catch (Exception e) { } } } protected void loadImage() throws IOException, ClassNotFoundException, SQLException { Connection con = null; PreparedStatement stmt = null; ResultSet rs = null; try { con = getConnection(); stmt = con.prepareStatement("select image from images"); rs = stmt.executeQuery(); while (rs.next()) { System.out.println("Getting blob"); Blob blob = rs.getBlob(1); System.out.println("Reading image"); BufferedImage img = ImageIO.read(blob.getBinaryStream()); System.out.println("img = " + img); JOptionPane.showMessageDialog(null, new JScrollPane(new JLabel(new ImageIcon(img)))); } } finally { try { rs.close(); } catch (Exception e) { } try { stmt.close(); } catch (Exception e) { } try { con.close(); } catch (Exception e) { } } } }