我有这种将BufferedImage写入IIOImage的代码。我的问题是原始照片仍然比新生成的图像具有更好的质量(我需要在图像上写一些数据并且我正在使用Graphics2D)。第二个问题是,新映像的大小比原始映像大得多(原始1.7MB,新的4.8MB)。完成此操作的其他方法是使用ImageIO.write(),但随后图像我无法设置压缩质量。有什么办法可以将byte []转换为BufferedImage,然后使用Graphics2D在图像上写入一些内容,然后获得质量良好且尺寸相同的新图像吗?
private void getJPGBytes(BufferedImage bi,ByteArrayOutputStream baos,String format) {
try {
JPEGImageWriteParam jpegParams = new JPEGImageWriteParam(null);
jpegParams.setCompressionmode(ImageWriteParam.MODE_EXPLICIT);
jpegParams.setCompressionQuality(1L);
final ImageWriter writer = ImageIO.getImageWritersByFormatName(format).next();
writer.setOutput(ImageIO.createImageOutputStream(baos));
writer.write(null,new IIOImage(bi,null,null),jpegParams);
writer.dispose();
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
}
public byte[] drawData(byte[] bytes,List<AIResponse> data) {
try {
ImageReader reader = ImageIO.getImageReadersBySuffix(getExtensionFromImage(bytes)).next();
reader.setInput(ImageIO.createImageInputStream(new ByteArrayInputStream(bytes)));
BufferedImage bi = reader.read(0);
Graphics2D g2d = (Graphics2D) bi.getGraphics();
g2d.setColor(new Color(168,61,40,255));
Stroke stroke = new BasicStroke(5.0f,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
g2d.setStroke(stroke);
for (AIResponse aiResponse : data) {
Polygon poly = new Polygon();
aiResponse.getcoordinates().forEach(coordinate -> {
poly.addPoint(coordinate.get(0).intvalue(),coordinate.get(1).intvalue());
});
g2d.drawPolygon(poly);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String format = getExtensionFromImage(bytes).toLowerCase();
if (format.equals("jpg") || format.equals("jpeg")) {
getJPGBytes(bi,baos,format);
} else {
getPNGBytes(bi,bytes);
}
bytes = baos.toByteArray();
} catch (IOException e) {
throw new ApplicationException(e.getMessage());
}
return bytes;
}