将图像压缩为字节数组

时间:2019-02-26 14:59:57

标签: java spring image jpa

一段时间后,在对我的数据库及其REST Api进行压力测试之后,发生了以下问题。

我们通过JPA / Hibernate将图像另存为 byte数组在Mysql数据库中,如下所示:

@Column(columnDefinition = "MEDIUMBLOB")
private byte[] photo;

它应该工作,除非有很多高质量的图像,而我想检索所有图像。然后响应时间太长,事件邮递员被卡住

因此,我正在寻找解决方案,以缩小这些字节数组。 有没有一种方法可以将图像压缩为字节数组? 还是也许是分页(不是我认为必须解决的最佳方法)吗?

谢谢。

2 个答案:

答案 0 :(得分:0)

我假设您面临的问题是,您在同一查询中读取了许多图像,并且它们占用了过多的内存,从而导致垃圾回收和其他问题。压缩图像无济于事,因为您需要在将其返回给客户端之前再次对其进行解压缩,而且大多数图像格式已经被压缩。

您可以改为查看streaming,在这里您无需将所有匹配的图像从数据库中读取到内存中,而是一次处理一个。确保您还流传输发送到客户端的数据。如果操作正确,则可以降低内存使用量,并且可以在读取其他图像之前将第一张图像发送给客户端,从而减少了写入第一个字节的时间并使响应迅速。

或者按照建议的注释之一操作,先读取元数据,然后一次读取一张图像的完整图像数据。

答案 1 :(得分:0)

如果图像为JPEG,则需要按每个级别进行照片质量压缩:反之则为高压缩和低质量。您可以/应该限制图像大小(宽度和高度)。请参阅ImageIO的ImageWriter和质量设置。

对于BLOB,您应该添加:

@Lob
@Column(columnDefinition = "MEDIUMBLOB")
private byte[] photo;

可能最好将image字段放在自己的数据库表中,这样可以更快地查询原始表。

如前所述,还可以将图像存储在文件系统上,也许使用生成的唯一ID:

UUID uuid = UUID.randomUUID();
String fileName = uuid.toString() + ".jpg";

通常,使用byte[]字段或本地对象不是最佳选择,因为它不必要地向服务器充电。在JPA之外,立即读取和写入响应会更好。如果您想要数据库中的内容,则可能是本机查询。