Я конвертирую SVG в изображение PNG с помощью Batik, но текст, который идет по нескольким строкам, отображается неправильно. Недетерминированным образом может случиться так, что сам текст больше не будет центрирован на конечном изображении.
В качестве примера рассмотрим эту часть стартового SVG:
Это правильный рендеринг, который я хочу получить и в PNG. Полученный PNG, кстати, выглядит так:
Как видите, текст в верхнем зеленом поле больше не центрирован.
Это часть SVG, которая определяет это (подозревая проблему со шрифтами, я также попытался удалить все font-family=""
, но безрезультатно):
<g transform="translate(184.68 -0.600364)">
<text fill="rgb(255, 255, 255)" fill-opacity="1" font-family="Kievit Pro" font-size="10px" font-style="normal" font-weight="normal" text-anchor="middle" transform="translate(48 0.429996)">
<tspan dy="1em" x="0">A simple activity, with</tspan>
<tspan dy="1.5em" x="0">a text that goes on t</tspan>
</text>
</g>
Если это может помочь, это код, который я использую для преобразования:
static byte[] convertToPng(byte[] byteSvgSmall) throws TranscoderException, IOException {
if (byteSvgSmall != null) {
byte[] byteImagePng = null;
ByteArrayInputStream bais = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream targetStream = null;
try {
targetStream = new ByteArrayInputStream(byteSvgSmall);
TranscoderInput input = new TranscoderInput(targetStream);
PNGTranscoder transcoder = new PNGTranscoder();
transcoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, new Float(diagramWidthInPixelsForPdf));
TranscoderOutput output = new TranscoderOutput(baos);
transcoder.transcode(input, output);
byte[] byteOutput = baos.toByteArray();
byteImagePng = new byte[byteOutput.length];
bais = new ByteArrayInputStream(baos.toByteArray());
bais.read(byteImagePng);
targetStream.close();
baos.flush();
return byteImagePng;
} catch (Exception e) {
BeanFactory
.getLogger()
.error(SVGTransformer.class,
"An error occurred. A null byte[] will be returned",
e);
return null;
} finally {
if (bais != null) bais.close();
if (baos != null) baos.close();
if (targetStream != null) targetStream.close();
}
}
return null;
}
И затем с возвращенным byte[]:
if (pngBytes != null) {
BufferedImage final_img = ImageIO.read(new ByteArrayInputStream(pngBytes));
File output_file = new File(imagepath);
ImageIO.write(final_img, "png", output_file);
}
Большое спасибо за любое понимание.