【问题标题】:Convert BufferedInputStream into image [duplicate]将 BufferedInputStream 转换为图像 [重复]
【发布时间】:2014-01-12 04:43:31
【问题描述】:

我无法将我的 blob 转换为缓冲图像,以便我可以使用它。我从使用 inputstream 上传的数据库中返回了一个 blob(jpg 图像)。在我的数据库中,它存储为我注意到的 BufferedInputStream。我得到 blob 就好了,它是一堆奇怪的符号,并说它是 jpg 所以图像必须很好。谁能发现我做错了什么?也许我把它转换错了?在 image = ImageIO.read(new ByteArrayInputStream(data));图片返回 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();
}

我如何写入数据库

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();
}

我如何将文件发送到我的 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);

【问题讨论】:

  • blob.getBytes()之后的数据是否填充了字节?
  • 是的,它充满了字节,并且与原始 jpg 的字节数几乎相同
  • 我会先检查文件。将data 写入文件并尝试使用一些图像查看器打开它。如果您有有效的 jpg 文件,请尝试通过 ImageIO.read(new File(...); 读取它。我认为问题在于数据不是有效的图像。
  • 您可以尝试使用ImageIO.createImageInputStream(new ByteArrayInputStream(data)),然后将其结果传递给ImageIO.read,但老实说,我怀疑它会起作用。能把你用来写的代码贴出来吗...
  • 好吧,如果 windows photo view 显示该图像似乎已损坏,则可能是页眉损坏或其他一些问题。您是否尝试过使用有效图片?

标签: java mysql web-services jersey inputstream


【解决方案1】:

首先验证uploadedInputStream 是一个有效的图像,可能通过使用ImageIO.write 将其写出来。您始终可以使用ImageIO.read 重新读入图像并将其写回ByteArrayInputStream ;)

我使用 H2 数据库做了一个快速测试。

我注意到了一些事情。 Blob#length 返回 long,而 Blob#getBytes 需要 int,这可能意味着您正在截断字节流。

另外,从 H2 的文档来看,Blob 的内容似乎没有保存在内存中,所以我改用了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) {
            }
        }

    }

}

【讨论】:

  • 谢谢你疯了!终于有人能帮我看到问题了。努力学习,还是新手!
  • 我已经很久没有写任何严肃的 SQL 了,所以这对我来说是一个学习曲线;)
  • @MadProgrammer,你随时准备提供帮助,+1 为好答案,每当我看到一个关于你的摇摆问题时,我都会记得
  • @JqueryLearner 不确定这是一个好的答案,但给了 OP 一些尝试的东西;)
猜你喜欢
  • 2011-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-12
  • 2013-12-28
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多