Java 中图像到 ByteArray 到 BLOB 和 BLOB 到 ByteArray 到图像的转换问题
Image to ByteArray to BLOB and BLOB to ByteArray to Image Conversion Issues in Java
在对 ByteArrays 和 BLOBS 进行大量学习之后,我设法编写了以下 Java 代码来将图像写入 Access DB(使用 ucanaccess)并将其写回磁盘。
当我将图像写回磁盘时,图像格式不正确或出现问题导致您无法打开该图像。
我知道将图像存储在数据库中不是一个好的做法,但是,这仅供我学习。
public static void Update_to_DB() throws SQLException, IOException {
String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
Connection conn = DriverManager.getConnection(URL);
//Statement stmt = conn.createStatement();
PreparedStatement p;
File ImgPath = new File("C:\Users\bharat.nanwani\Desktop\Desert.jpg");
BufferedImage bufferedimage = ImageIO.read(ImgPath);
WritableRaster raster = bufferedimage.getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
byte[] bytearray = date.getdata();
String query = "INSERT INTO Images(data) VALUES(?);";
p = conn.prepareStatement(query);
p.setBinaryStream(1, new ByteArrayInputStream(bytearray),bytearray.length);
p.execute();
}
public static void update_to_DISK() throws SQLException, IOException {
String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
Connection conn = DriverManager.getConnection(URL);
PreparedStatement p;
ResultSet rs;
String query = "SELECT Data FROM Images";
p=conn.prepareStatement(query);
rs = p.executeQuery();
if (rs.next()) {
Blob blob = rs.getBlob("Data");
byte[] bytearray = blob.getBytes(1L, (int)blob.length());
FileOutputStream fos = new FileOutputStream("C:\Users\bharat.nanwani\Desktop\New Folder\test.jpg");
fos.write(bytearray);
fos.close();
System.out.println(bytearray);
}
}
首先,你应该把它分成两部分:
- 在数据库中存储二进制数据并检索它
- 正在加载图像文件并再次保存
无需使用数据库来测试第二部分 - 您应该通过加载图像并直接保存到文件来诊断问题,跳过数据库。
不,我认为问题在于您正在从 WritableRaster 的数据缓冲区复制数据,然后将其保存到 .jpg
文件中。那时它不是 jpeg - 它是 WritableRaster
使用的任何内部格式。
如果您想要 jpeg 文件,则根本不需要使用 ImageIO - 因为您已经开始 使用 jpeg 文件。如果您想以相同的图像开始和结束,只需复制文件(或将文件保存到数据库中,在您的情况下)。那只是将文件视为字节。
如果你需要做一些事情,比如以不同的格式保存,或者以不同的大小保存,那么你应该要求 ImageIO 库将图像保存为 JPEG再次,重新编码...然后将结果存储为文件或数据库等
使用FileInputStream
而不是WritableRaster
读取图像文件
然后使用PreparedStatement
的setBinaryStream()
方法将图像文件存储在数据库中..
它将以字节为单位存储文件。
同时从数据库取回文件时使用 ResultSet
的 getBytes()
方法并使用 FileOutputStream
存储它
public static void Update_to_DB() throws SQLException, IOException {
String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
Connection conn = DriverManager.getConnection(URL);
//Statement stmt = conn.createStatement();
PreparedStatement p;
File ImgPath = new File("C:\Users\bharat.nanwani\Desktop\Desert.jpg");
FileInputStream fin = new FileInputStream(ImgPath);
String query = "INSERT INTO Images(Data) VALUES(?);";
p = conn.prepareStatement(query);
p.setBinaryStream(1, fin);
p.execute();
}
public static void update_to_DISK() throws SQLException, IOException {
String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
Connection conn = DriverManager.getConnection(URL);
PreparedStatement p;
ResultSet rs;
String query = "SELECT Data FROM Images";
p = conn.prepareStatement(query);
rs = p.executeQuery();
if (rs.next()) {
byte[] bytearray = rs.getBytes("Data");
FileOutputStream fos = new FileOutputStream("C:\Users\bharat.nanwani\Desktop\New Folder\test.jpg");
fos.write(bytearray);
fos.close();
System.out.println(bytearray);
}
}
它会解决你的问题..
下面是我正在做的写入数据库的操作 -
public static void main(String[] Args) throws SQLException, IOException {
String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
Connection conn = DriverManager.getConnection(URL);
PreparedStatement p;
File ImgPath = new File("C:\Users\bharat.nanwani\Desktop\Desert.jpg");
FileInputStream fileinput = new FileInputStream(ImgPath);
byte[] bytearray = new byte[(int)ImgPath.length()];
String query = "INSERT INTO Images(data) VALUES(?);";
p = conn.prepareStatement(query);
//p.setBinaryStream(1, new ByteArrayInputStream(bytearray),bytearray.length);
p.setBytes(1, bytearray);
p.execute();
}
在对 ByteArrays 和 BLOBS 进行大量学习之后,我设法编写了以下 Java 代码来将图像写入 Access DB(使用 ucanaccess)并将其写回磁盘。
当我将图像写回磁盘时,图像格式不正确或出现问题导致您无法打开该图像。
我知道将图像存储在数据库中不是一个好的做法,但是,这仅供我学习。
public static void Update_to_DB() throws SQLException, IOException {
String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
Connection conn = DriverManager.getConnection(URL);
//Statement stmt = conn.createStatement();
PreparedStatement p;
File ImgPath = new File("C:\Users\bharat.nanwani\Desktop\Desert.jpg");
BufferedImage bufferedimage = ImageIO.read(ImgPath);
WritableRaster raster = bufferedimage.getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
byte[] bytearray = date.getdata();
String query = "INSERT INTO Images(data) VALUES(?);";
p = conn.prepareStatement(query);
p.setBinaryStream(1, new ByteArrayInputStream(bytearray),bytearray.length);
p.execute();
}
public static void update_to_DISK() throws SQLException, IOException {
String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
Connection conn = DriverManager.getConnection(URL);
PreparedStatement p;
ResultSet rs;
String query = "SELECT Data FROM Images";
p=conn.prepareStatement(query);
rs = p.executeQuery();
if (rs.next()) {
Blob blob = rs.getBlob("Data");
byte[] bytearray = blob.getBytes(1L, (int)blob.length());
FileOutputStream fos = new FileOutputStream("C:\Users\bharat.nanwani\Desktop\New Folder\test.jpg");
fos.write(bytearray);
fos.close();
System.out.println(bytearray);
}
}
首先,你应该把它分成两部分:
- 在数据库中存储二进制数据并检索它
- 正在加载图像文件并再次保存
无需使用数据库来测试第二部分 - 您应该通过加载图像并直接保存到文件来诊断问题,跳过数据库。
不,我认为问题在于您正在从 WritableRaster 的数据缓冲区复制数据,然后将其保存到 .jpg
文件中。那时它不是 jpeg - 它是 WritableRaster
使用的任何内部格式。
如果您想要 jpeg 文件,则根本不需要使用 ImageIO - 因为您已经开始 使用 jpeg 文件。如果您想以相同的图像开始和结束,只需复制文件(或将文件保存到数据库中,在您的情况下)。那只是将文件视为字节。
如果你需要做一些事情,比如以不同的格式保存,或者以不同的大小保存,那么你应该要求 ImageIO 库将图像保存为 JPEG再次,重新编码...然后将结果存储为文件或数据库等
使用FileInputStream
而不是WritableRaster
读取图像文件
然后使用PreparedStatement
的setBinaryStream()
方法将图像文件存储在数据库中..
它将以字节为单位存储文件。
同时从数据库取回文件时使用 ResultSet
的 getBytes()
方法并使用 FileOutputStream
public static void Update_to_DB() throws SQLException, IOException {
String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
Connection conn = DriverManager.getConnection(URL);
//Statement stmt = conn.createStatement();
PreparedStatement p;
File ImgPath = new File("C:\Users\bharat.nanwani\Desktop\Desert.jpg");
FileInputStream fin = new FileInputStream(ImgPath);
String query = "INSERT INTO Images(Data) VALUES(?);";
p = conn.prepareStatement(query);
p.setBinaryStream(1, fin);
p.execute();
}
public static void update_to_DISK() throws SQLException, IOException {
String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
Connection conn = DriverManager.getConnection(URL);
PreparedStatement p;
ResultSet rs;
String query = "SELECT Data FROM Images";
p = conn.prepareStatement(query);
rs = p.executeQuery();
if (rs.next()) {
byte[] bytearray = rs.getBytes("Data");
FileOutputStream fos = new FileOutputStream("C:\Users\bharat.nanwani\Desktop\New Folder\test.jpg");
fos.write(bytearray);
fos.close();
System.out.println(bytearray);
}
}
它会解决你的问题..
下面是我正在做的写入数据库的操作 -
public static void main(String[] Args) throws SQLException, IOException {
String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
Connection conn = DriverManager.getConnection(URL);
PreparedStatement p;
File ImgPath = new File("C:\Users\bharat.nanwani\Desktop\Desert.jpg");
FileInputStream fileinput = new FileInputStream(ImgPath);
byte[] bytearray = new byte[(int)ImgPath.length()];
String query = "INSERT INTO Images(data) VALUES(?);";
p = conn.prepareStatement(query);
//p.setBinaryStream(1, new ByteArrayInputStream(bytearray),bytearray.length);
p.setBytes(1, bytearray);
p.execute();
}