从 Mysql 数据库中读取图像并在 Java 中再次将其重新发送到数据库
Reading an image from Mysql DB and resend it again to DB in Java
我在将图像再次写入数据库时遇到问题!这就是我要做的!
用户通过一个Jframe从硬盘中选择一张图片,我读取图片的内容,然后我将它发送到数据库,这里我没有任何问题!
用户再次打开 Jframe 编辑其他内容时出现的问题!我知道如果您没有看到整个代码,您可能会感到模糊!我知道如何读取文件然后将其编码为十六进制代码以将其发送到数据库 - mysql 中的 blob 数据类型 -
这是我关于读取图像并将其转换为十六进制代码的代码:这非常有效,我没有遇到任何问题
private String makeBlob(String paths) {
char[] hexArray = "0123456789abcdef".toCharArray();
Path path = Paths.get(paths);
byte[] bytes = null;
try {
bytes = Files.readAllBytes(path);
} catch (IOException ex) {
Logger.getLogger(LuggageAdd.class.getName()).log(Level.SEVERE, null, ex);
}
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
String test = new String(hexChars);
return "0x" + test;
}
注意:图像是在我的 jFrame 上使用 jLabel 显示的!所以它是 imageIcon
有没有办法对现有的图像对象做同样的事情!我的意思是,在上面我从一个文件(图像路径)生成一个十六进制代码,但我想从一个现有的 imageIcon 对象生成一个十六进制代码??如果我能做到这一点,那么在图像还没有被编辑的情况下,将很容易将图像重新发送到数据库!
这是我从数据库中获取图像的方法:
public ImageIcon getImage(int id) {
BufferedImage bufferedImage = null;
try {
String ss = "SELECT image FROM luggage WHERE ID = " + id + " ";
ResultSet result = this.databaseConnection.doQuery(ss);
while (result.next()) {
Blob blob = result.getBlob("image");
int blobLength = (int) blob.length();
byte[] blobAsBytes = blob.getBytes(1, blobLength);
bufferedImage = ImageIO.read(new ByteArrayInputStream(blobAsBytes));
}
} catch (Exception ex) {
ex.printStackTrace(); }
return new ImageIcon(bufferedImage.getScaledInstance(128, 128, Image.SCALE_SMOOTH));
}
PS: 我试过另一种解决方法,我读取图片并暂时写入硬盘,然后重新写入数据库,但出现保存时图片大小增加的问题它到磁盘!如果原始图像大小是 1.9MB 那么它将是 2.40MB 。这效率不高,因为我想以相同的质量和大小重新保存我的图像,除此之外我还有图像大小的限制。
所以解决它的唯一方法就是知道如何获取图像图标的内容并将其重新发送到数据库!
谢谢:)
您可以将(blobAsBytes 的)图像 blob 引用存储为图像源。
或
使用 ImageIcon 的方法 getImage()
并将图像转换为字节。
例如
try {
// retrieve image
BufferedImage bi = getMyImage();
File outputfile = new File("saved.png");
ImageIO.write(bi, "png", outputfile);
} catch (IOException e) {
...
}
或者不保存到文件而是保存到 ByteArrayOutputStream。
但对我来说第一种方法更好,因为 ImageIcon 保留 scled 实例而不是原始图像。
我在将图像再次写入数据库时遇到问题!这就是我要做的! 用户通过一个Jframe从硬盘中选择一张图片,我读取图片的内容,然后我将它发送到数据库,这里我没有任何问题! 用户再次打开 Jframe 编辑其他内容时出现的问题!我知道如果您没有看到整个代码,您可能会感到模糊!我知道如何读取文件然后将其编码为十六进制代码以将其发送到数据库 - mysql 中的 blob 数据类型 - 这是我关于读取图像并将其转换为十六进制代码的代码:这非常有效,我没有遇到任何问题
private String makeBlob(String paths) {
char[] hexArray = "0123456789abcdef".toCharArray();
Path path = Paths.get(paths);
byte[] bytes = null;
try {
bytes = Files.readAllBytes(path);
} catch (IOException ex) {
Logger.getLogger(LuggageAdd.class.getName()).log(Level.SEVERE, null, ex);
}
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
String test = new String(hexChars);
return "0x" + test;
}
注意:图像是在我的 jFrame 上使用 jLabel 显示的!所以它是 imageIcon
有没有办法对现有的图像对象做同样的事情!我的意思是,在上面我从一个文件(图像路径)生成一个十六进制代码,但我想从一个现有的 imageIcon 对象生成一个十六进制代码??如果我能做到这一点,那么在图像还没有被编辑的情况下,将很容易将图像重新发送到数据库!
这是我从数据库中获取图像的方法:
public ImageIcon getImage(int id) {
BufferedImage bufferedImage = null;
try {
String ss = "SELECT image FROM luggage WHERE ID = " + id + " ";
ResultSet result = this.databaseConnection.doQuery(ss);
while (result.next()) {
Blob blob = result.getBlob("image");
int blobLength = (int) blob.length();
byte[] blobAsBytes = blob.getBytes(1, blobLength);
bufferedImage = ImageIO.read(new ByteArrayInputStream(blobAsBytes));
}
} catch (Exception ex) {
ex.printStackTrace(); }
return new ImageIcon(bufferedImage.getScaledInstance(128, 128, Image.SCALE_SMOOTH));
}
PS: 我试过另一种解决方法,我读取图片并暂时写入硬盘,然后重新写入数据库,但出现保存时图片大小增加的问题它到磁盘!如果原始图像大小是 1.9MB 那么它将是 2.40MB 。这效率不高,因为我想以相同的质量和大小重新保存我的图像,除此之外我还有图像大小的限制。
所以解决它的唯一方法就是知道如何获取图像图标的内容并将其重新发送到数据库!
谢谢:)
您可以将(blobAsBytes 的)图像 blob 引用存储为图像源。
或
使用 ImageIcon 的方法 getImage()
并将图像转换为字节。
例如
try {
// retrieve image
BufferedImage bi = getMyImage();
File outputfile = new File("saved.png");
ImageIO.write(bi, "png", outputfile);
} catch (IOException e) {
...
}
或者不保存到文件而是保存到 ByteArrayOutputStream。
但对我来说第一种方法更好,因为 ImageIcon 保留 scled 实例而不是原始图像。