Category Archives: batik

Error importing org.apache.batik

I'm trying to use the Java-based toolkit Batik. I have downloaded Apache Batik 1.8 and edited the environmental variable Path to include the path where I put its files (C:\Program Files\Batik\batik-1.8). In a Java file that I want to compile, the following imports are present.

import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.dom.GenericDOMImplementation;

And when I try compiling this, the following errors occurs.

error: package org.apache.batik.svggen does not exist
error: package org.apache.batik.dom does not exist

What have I missed?

Prevent Caching .svg Images on Application Server

I have a JWS application that caches several different resource types. However, I do not want to cache .svg images. It seems that the framework does not honor the server side cache control HTTP headers that I have set.

I was wondering if there is some other way that I could load .svg images without caching. I am open to putting a solution in my loadSVGDocument() method, but my code is currently built around Apache Batik for loading .svg files. Is there a solution to pass an InputStream with a noCache flag within the Batik library similar to what DocumentBuilderFactory provides below?

URL url = new URL(fileLocation);
URLConnection connection = url.openConnection();
// Prevent JavaWebStart from returning cached copy.
connection.setUseCaches(false);

// Now fetch the content, e.g.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder(); 
Document doc = db.parse(connection.getInputStream());

Here is my current loadSVGDocument() method that uses several Apache Batik fields:

public void loadSVGDocument(final String url)
{
    System.out.println("THE SVG URL: " + url);
    String oldURI = null;
    if (svgDocument != null)
    {
       oldURI = svgDocument.getURL();
    }

    final ParsedURL newURI = new ParsedURL(oldURI, url);
    String theUrl = newURI.toString();
    fragmentIdentifier = newURI.getRef();

    loader = new DocumentLoader(userAgent);
    nextDocumentLoader = new SVGDocumentLoader(theUrl, loader);
    nextDocumentLoader.setPriority(Thread.NORM_PRIORITY);

    Iterator it = svgDocumentLoaderListeners.iterator();
    while (it.hasNext())
    {
       nextDocumentLoader
          .addSVGDocumentLoaderListener((SVGDocumentLoaderListener) it.next());
    }

    documentLoader = nextDocumentLoader;
    nextDocumentLoader = null;
    documentLoader.run();
}

Generate JPG from SVG using Apache Batik

I'm trying to turn a .svg file into a .jpg or .png file. Right now I'm trying to use Apache Batik Transcoder (Link).

This is my code right now: (official code from here)

// Create a JPEG transcoder
JPEGTranscoder t = new JPEGTranscoder();

// Set the transcoding hints.
t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY,
    new Float(.8));

// Create the transcoder input.
String svgURI = new File("C:/test.svg").toURL().toString();
TranscoderInput input = new TranscoderInput(svgURI);

// Create the transcoder output.
OutputStream ostream = new FileOutputStream("C:/out.jpg");
TranscoderOutput output = new TranscoderOutput(ostream);

// Save the image.
t.transcode(input, output);

// Flush and close the stream.
ostream.flush();
ostream.close();
System.exit(0);

But it gives my this error:

Exception in thread "main" org.apache.batik.transcoder.TranscoderException: null

Enclosed Exception:

null

at org.apache.batik.transcoder.image.ImageTranscoder.transcode(Unknown Source)

at org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(Unknown Source)

at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(Unknown Source)

at SaveAsJPEG.main(SaveAsJPEG.java:27)

I don't know what to do as this is the code from their website (!). So if you know how to solve it or have another idea how I can turn my .svg pictures into .jpg and .png's let me know.

Batik – how to read an svg file, modify the document and write back to the file

I have an SVG file that I'd like to use Apache Batik library to read into the Document, add a path to it and then write the Document back to the SVG file. However, it seems like I could read the SVG into the Document and parse the path data but to write the Document back to the SVG file, I need to explicitly call the draw function. Here is my code

String parser = `XMLResourceDescriptor.getXMLParserClassName()`;
SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
String uri = resolveURL("GolferMe2ToCut5.25H.svg");
Document doc = f.createSVGDocument(uri);
//Write the doc back to the SVG file
Writer out;
try {
  out = new OutputStreamWriter(System.out, "UTF-8");
  svg.drawLine(0, 100, 100, 200);
  svg.stream(out, true);  //I expected this to print out the content of the svg file to the standard output.  However, it only printed out an empty svg file
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (SVGGraphics2DIOException e) {
e.printStackTrace();
}

Is my assumption correct: the Batik library SAXSVGDocumentFactory.createDocument() does read the SVG file and allows you to parse the content, but to write that content back out, I'll have to call some api, like draw()?

JSVGCanvas does not update the graphic after new elements being added

using: Apache batik (SVG) , NetBeans IDE, NetBeans platform, Java

I have an application with a SVG displayed with batik and the JSVGCanvas Component.

I also called svg.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);

This is the SVG file:

<svg width="500" height="400" viewBox="0 0 250 200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="hi" style="color:black; stroke:currentColor; stroke-width:0.4;">
    <g id="ks">
        <text id="textX" x="0" y="5" style="font-family:Arial; font-size:4.00pt; text-anchor:start">100%</text>
        <text id="textY" x="5" y="105" style="font-family:Arial; font-size:4.00pt; text-anchor:start">0%</text>
    </g>
</g>

This simple SVG is first displayed in the application just like it is now. Now I get new input from the application and need to add new Elements to the SVG document. I am doing this with the SVGDocument, which i get from JSVGCanvas. Here is an example:

Runnable run = new Runnable()
{
  @Override
  public void run()
  {
      Element elementById = SVGUtilities.getElementById(svgDocument, "g", "hi");
      Element createElement = svgDocument.createElement("g");
      createElement.setAttribute("id", "myID");
      Element rect = SVGUtilities.createRect(
        svgDocument, String.valueOf(xValue), yValue, String.valueOf(BARWIDTH), 
        String.valueOf(barHeight), color);
      createElement.appendChild(rect);
      elementById.appendChild(createElement);
  }
};

To execute the changes I now wrap these lines in a Runnable and put it in the UpdateManager Queue.

RunnableQueue updateRunnableQueue = updateManager.getUpdateRunnableQueue();
updateRunnableQueue.invokeAndWait(run);
((JSVGCanvas)canvas).setSVGDocument((SVGDocument)doc);

The JSVGCanvas does not update the graphic.

Some additional information:

  • I tried it also with invokeLater(run); this did not work, too
  • I DONĀ“T change the file, JUST the SVGDocument. So I do not write the changes to the file. I just change the "Document" instance.
  • I printed the document instance to the console for logging and the result is exactly what i wanted, so the document DOES contain the right and new elements.

The result for the SVG in the console is:

<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" contentScriptType="text/ecmascript" width="500" zoomAndPan="magnify" contentStyleType="text/css" viewBox="0 0 250 200" height="400" preserveAspectRatio="xMidYMid meet" version="1.0">
<g style="color:black; stroke:currentColor; stroke-width:0.4;" id="hi">
    <g id="ks">
        <text x="0" id="textX" y="5" style="font-family:Arial; font-size:4.00pt; text-anchor:start">100%</text>
        <text x="5" id="textY" y="105" style="font-family:Arial; font-size:4.00pt; text-anchor:start">0%</text>
    </g>
<g id="25.0">
        <rect x="20.0" width="20.0" y="5.0" height="7.142857142857142" style="fill:#ff0000"/>
    </g>
</g>

Do you have any idea why my graphic does not update? I searched for days now and my changes (UpdateManager Queue, setSVGDocument, etc.) do not work. I dont know what to do now...

Thank you in advance.

Greetings Tobias

Set Windows font on Linux in SVG with Apache Batik

I'm developing a simple web application that provides an URL for rendering an SVG image. I use Apache Batik library for SVG rendering and I have a problem with setting font-family. I would like the resulting SVG to look identical (as it can) when viewed from any browser (mainly Chrome, FF and Edge) and any OS (mainly Linux and Windows). The problem is, that as I see, Batik uses some internal logic that loads fonts from the local system, and this prevents cross-platform behaviour.

To be more precise: my webapp runs on Ubuntu Linux, and I set font-family:'DejaVu Sans' to my graphics. This works perfectly when the client uses Linux, but on Windows, obviously this font does not exist. I tried to set font-family according to the User-Agent header in the request, but when I set font-family:'Verdana' for Windows clients, Batik tries to load the 'Verdana' font, and it obviously fails.

I tried to set the attribute like this: font-family:'DejaVu Sans',Verdana but Batik can not handle comma-separated list of valid font families. Is there any way to resolve this besides installing the Verdana font on the server?

In Apache Batik: How to listen to UI (mouse, keyboard) events for a given GVT GraphicsNode

Is there a way to listen directly to a gvt GraphicsNode for UI-events in Apache Batik? There are specific listener classes for doing so (GraphicsNodeMouseListener, etc.), but there does not seem to be any way to add such a listener to a GraphicsNode instance. Ie -- no "addGraphicsNodeMouseListener" method. There is an EventDispatcher class in package org.apache.batik.gvt.event, which offers such methods, but it doesn't seem to be directly related to any of the GraphicsNode implementors (AbstractGraphicsNode, and so on).

So how is this accomplished? Or can it be? I ran across one obscure post that stated that the ui-listening functionality had been removed in later versions (i'm using 1.8, i believe). I'd like to be able to directly listen to the internal AWT events, rather than having to listen through the SVG document events, if possible.

Any clue?

Thanks in advance.

SVG to PNG – Batik

When converting from SVG to PNG with Apache Batik I sometimes get strange errors. For example for this SVG https://www.macstories.net/app/themes/macstories4/images/logo-shape-bw.svg it throws an exception, but not for this https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg

Here is my code:

package com.stackoverflow.batik;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.batik.transcoder.SVGAbstractTranscoder;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;

public class Converter {

    public static BufferedImage convertSVGToPNG(String url) throws TranscoderException, IOException {
        ByteArrayOutputStream resultByteStream = new ByteArrayOutputStream();

        TranscoderInput transcoderInput = new TranscoderInput(url);
        TranscoderOutput transcoderOutput = new TranscoderOutput(resultByteStream);

        PNGTranscoder pngTranscoder = new PNGTranscoder();
        pngTranscoder.addTranscodingHint(SVGAbstractTranscoder.KEY_HEIGHT, 256f);
        pngTranscoder.addTranscodingHint(SVGAbstractTranscoder.KEY_WIDTH, 256f);
        pngTranscoder.transcode(transcoderInput, transcoderOutput);

        resultByteStream.flush();

        return ImageIO.read(new ByteArrayInputStream(resultByteStream.toByteArray()));
    }

    public static void main(String args[]) throws TranscoderException, IOException {
        BufferedImage image = convertSVGToPNG("https://www.macstories.net/app/themes/macstories4/images/logo-shape-bw.svg");
        assert image.getWidth() == 256;
        assert image.getHeight() == 256;
    }
}

And this is the exception

Exception in thread "main" org.apache.batik.transcoder.TranscoderException: null
Enclosed Exception:
The current document is unable to create an element of the requested type (namespace: http://www.w3.org/2000/svg, name: description).
        at org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(Unknown Source)
        at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(Unknown Source)
        at com.stackoverflow.batik.Converter.convertSVGToPNG(Converter.java:25)
        at com.stackoverflow.batik.Converter.main(Converter.java:33)

Am I doing something wrong?

Java writing eps file gives strange output

I am generating an EPS-File with following Code:

final EPSDocumentGraphics2D epsGraphic = new EPSDocumentGraphics2D(
                    false);
final GraphicContext ctx = new GraphicContext();
epsGraphic.setGraphicContext(ctx);
epsGraphic.setupDocument(epsFile, EPSSIZE, EPSSIZE);

Font font = FontUtils.INSTANCE.getFont(lock.getFont());
font = font.deriveFont(FONTSIZE);
epsGraphic.setFont(font);

FontMetrics fontMetrics = epsGraphic.getFontMetrics();

float yPos = 100F;
float textWidth;
if (!lock.getTextOne().isEmpty()) {
    textWidth = fontMetrics.stringWidth(lock.getTextOne());
    final Shape text = this.generateShapeFromText(font,
            lock.getTextOne(), (EPSSIZE - textWidth) / HALF,
            yPos);
    epsGraphic.draw(text);


private Shape generateShapeFromText(final Font font, final String text,
        final float x, final float y) {
    final BufferedImage img = new BufferedImage(BUFFIMGSIZE, BUFFIMGSIZE,
            BufferedImage.TYPE_INT_ARGB);
    final Graphics2D graphics = img.createGraphics();

    try {
        final GlyphVector vect = font.createGlyphVector(
                graphics.getFontRenderContext(), text);
        return vect.getOutline(x, y);
    } finally {
        graphics.dispose();
    }
}

But after writing it to File, my EPS looks like that:

EPS File

Opening the EPS-File with InkScape is no Problem, everything looks fine. But opening it with another Program, it does not. The graphic in the center (I know bad quality..) shows that the graphic is upside down. So what happens to my Texts? Where is the fault? I just switched from VectorGraphics2D to Apache XMLGraphics. Which more Settings do I need in the XMLGraphics so they are displayed correctly?