Convert BufferedInputStream into image [duplicate]

蓝咒 提交于 2020-01-08 16:59:28

问题


Im having trouble turning my blob into a buffered image so I can use it. I'm getting a blob (jpg image) back from my database I uploaded using inputstream. In my database it is stored as BufferedInputStream I notice. I get the blob just fine, its a bunch of weird symbols and says its a jpg so the image has to be fine. Can anyone spot what I'm doing wrong? Maybe im converting it wrong? At image = ImageIO.read(new ByteArrayInputStream(data)); Image returns 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();
}

How I write to 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();
}

How I send the file to my 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);

回答1:


Start by verifying that uploadedInputStream is a valid image, prehaps by writing it out using ImageIO.write. You can always use ImageIO.read to read the image back in and write it back out to a ByteArrayInputStream ;)

I did a quick test using H2 database.

A few things I noted. Blob#length returns a long, while Blob#getBytes expects an int, this could mean you're truncating the byte stream.

Also, from the documentation of H2, it would seem that the Blob contents is not kept in memory, so I use the getBinaryStream instead.

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) {
            }
        }

    }

}


来源:https://stackoverflow.com/questions/20752432/convert-bufferedinputstream-into-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!