У меня есть этот кусок кода, который записывает BufferedImage в IIOImage. Моя проблема в том, что исходная фотография по-прежнему имеет лучшее качество по сравнению с новым сгенерированным изображением (мне нужно записать некоторые данные на изображении, и я использую Graphics2D). Вторая проблема заключается в том, что новое изображение намного больше исходного (исходное 1,7 МБ, новое 4,8 МБ). Другой способ сделать это - использовать 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, baos, bytes);
}
bytes = baos.toByteArray();
} catch (IOException e) {
throw new ApplicationException(e.getMessage());
}
return bytes;
}