用于加载SVG图像的必需蜡染罐

时间:2014-07-17 12:19:38

标签: java swing maven svg batik

我使用batik-transcoder读取SVG文件并将它们转换为BufferedImage。我的问题是,maven下载了大约19个另外的jar来编译我的代码。我的用例并不真正需要哪些罐子?

我用于转换的代码是here
maven下载的罐子列表是:

[INFO] |  +- org.apache.xmlgraphics:batik-transcoder:jar:1.7:compile
[INFO] |  |  +- org.apache.xmlgraphics:fop:jar:0.94:compile
[INFO] |  |  |  +- org.apache.xmlgraphics:xmlgraphics-commons:jar:1.2:compile
[INFO] |  |  |  +- org.apache.avalon.framework:avalon-framework-api:jar:4.3.1:compile
[INFO] |  |  |  \- org.apache.avalon.framework:avalon-framework-impl:jar:4.3.1:compile
[INFO] |  |  +- org.apache.xmlgraphics:batik-awt-util:jar:1.7:compile
[INFO] |  |  +- org.apache.xmlgraphics:batik-bridge:jar:1.7:compile
[INFO] |  |  |  +- org.apache.xmlgraphics:batik-anim:jar:1.7:compile
[INFO] |  |  |  +- org.apache.xmlgraphics:batik-css:jar:1.7:compile
[INFO] |  |  |  +- org.apache.xmlgraphics:batik-ext:jar:1.7:compile
[INFO] |  |  |  +- org.apache.xmlgraphics:batik-parser:jar:1.7:compile
[INFO] |  |  |  +- org.apache.xmlgraphics:batik-script:jar:1.7:compile
[INFO] |  |  |  \- xalan:xalan:jar:2.6.0:compile
[INFO] |  |  +- org.apache.xmlgraphics:batik-dom:jar:1.7:compile
[INFO] |  |  +- org.apache.xmlgraphics:batik-gvt:jar:1.7:compile
[INFO] |  |  +- org.apache.xmlgraphics:batik-svg-dom:jar:1.7:compile
[INFO] |  |  +- org.apache.xmlgraphics:batik-svggen:jar:1.7:compile
[INFO] |  |  +- org.apache.xmlgraphics:batik-util:jar:1.7:compile
[INFO] |  |  +- org.apache.xmlgraphics:batik-xml:jar:1.7:compile
[INFO] |  |  \- xml-apis:xml-apis-ext:jar:1.3.04:compile

P.S。关于另一个SVG库的建议也是受欢迎的。我已经看过SVGSalamander了。它允许我想要的东西,但它看起来不像一个设计良好且支持良好的lib(恕我直言)。

1 个答案:

答案 0 :(得分:0)

如果使用gradle,则可以使用以下方式包括最小依赖项:

  implementation 'org.apache.xmlgraphics:batik-anim:1.13'
  implementation 'org.apache.xmlgraphics:batik-awt-util:1.13'
  implementation 'org.apache.xmlgraphics:batik-bridge:1.13'
  implementation 'org.apache.xmlgraphics:batik-css:1.13'
  implementation 'org.apache.xmlgraphics:batik-dom:1.13'
  implementation 'org.apache.xmlgraphics:batik-ext:1.13'
  implementation 'org.apache.xmlgraphics:batik-gvt:1.13'
  implementation 'org.apache.xmlgraphics:batik-parser:1.13'
  implementation 'org.apache.xmlgraphics:batik-script:1.13'
  implementation 'org.apache.xmlgraphics:batik-svg-dom:1.13'
  implementation 'org.apache.xmlgraphics:batik-svggen:1.13'
  implementation 'org.apache.xmlgraphics:batik-transcoder:1.13'
  implementation 'org.apache.xmlgraphics:batik-util:1.13'
  implementation 'org.apache.xmlgraphics:batik-xml:1.13'

JasperReports 5.0建议deploying reports到服务器时,基本上建议相同的集合。区别在于,蜡染转码器(相对较新?)不在他们的清单上(尽管我认为以后的JasperReports版本需要它):

batik-anim.jar
batik-awt-util.jar
batik-bridge.jar
batik-css.jar
batik-dom.jar
batik-ext.jar
batik-gvt.jar
batik-parser.jar
batik-script.jar
batik-svg-dom.jar
batik-svggen.jar
batik-util.jar
batik-xml.jar

获得一切:

  implementation 'org.apache.xmlgraphics:batik-all:1.13'

根据需要更改版本号。

注意:我仅针对两个SVG插图进行了测试。两者都完美无瑕。根据您的要求,可能有一些不需要的依赖项(例如batik-anim)。


SVG Salamander是另一个SVG引擎。比蜡染更轻,但不那么坚固。请注意,蜡染无法轻松处理文本flowRoot元素,并可能导致出现黑框。要消除黑框,需要删除所有flowRoot元素,这可能需要一些时间。 (另一种可能性是对SVG文件执行XSL转换以解决flowRoot问题,但是这种方法可能无法解决所有遇到的问题。)


下面是一个示例SVGRasterizer类,该类构建并使用上述Batik库文件的子集:

public class SVGRasterizer {
  private final static SAXSVGDocumentFactory mFactory =
      new SAXSVGDocumentFactory( getXMLParserClassName() );

  private final static Map<Object, Object> RENDERING_HINTS = Map.of(
      KEY_ALPHA_INTERPOLATION,
      VALUE_ALPHA_INTERPOLATION_QUALITY,
      KEY_INTERPOLATION,
      VALUE_INTERPOLATION_BICUBIC,
      KEY_ANTIALIASING,
      VALUE_ANTIALIAS_ON,
      KEY_COLOR_RENDERING,
      VALUE_COLOR_RENDER_QUALITY,
      KEY_DITHERING,
      VALUE_DITHER_DISABLE,
      KEY_RENDERING,
      VALUE_RENDER_QUALITY,
      KEY_STROKE_CONTROL,
      VALUE_STROKE_PURE,
      KEY_FRACTIONALMETRICS,
      VALUE_FRACTIONALMETRICS_ON,
      KEY_TEXT_ANTIALIASING,
      VALUE_TEXT_ANTIALIAS_OFF
  );

  private static class BufferedImageTranscoder extends ImageTranscoder {
    private BufferedImage mImage;

    @Override
    public BufferedImage createImage( final int w, final int h ) {
      return new BufferedImage( w, h, BufferedImage.TYPE_INT_ARGB );
    }

    @Override
    public void writeImage(
        final BufferedImage image, final TranscoderOutput output ) {
      mImage = image;
    }

    public Image getImage() {
      return mImage;
    }

    @Override
    protected ImageRenderer createRenderer() {
      final ImageRenderer renderer = super.createRenderer();
      final RenderingHints hints = renderer.getRenderingHints();
      hints.putAll( RENDERING_HINTS );

      renderer.setRenderingHints( hints );

      return renderer;
    }
  }

  /**
   * Rasterizes the vector graphic file at the given URL. If any exception
   * happens, a red circle is returned instead.
   *
   * @param url   The URL to a vector graphic file, which must include the
   *              protocol scheme (such as file:// or https://).
   * @param width The number of pixels wide to render the image. The aspect
   *              ratio is maintained.
   * @return Either the rasterized image upon success or a red circle.
   */
  public static Image rasterize( final String url, final int width ) {
    try {
      return rasterize( new URL( url ), width );
    } catch( final Exception e ) {
      return createPlaceholderImage( width );
    }
  }

  /**
   * Converts an SVG drawing into a rasterized image that can be drawn on
   * a graphics context.
   *
   * @param url   The path to the image (can be web address).
   * @param width Scale the image width to this size (aspect ratio is
   *              maintained).
   * @return The vector graphic transcoded into a raster image format.
   * @throws IOException         Could not read the vector graphic.
   * @throws TranscoderException Could not convert the vector graphic to an
   *                             instance of {@link Image}.
   */
  public static Image rasterize( final URL url, final int width )
      throws IOException, TranscoderException {
    return rasterize(
        (SVGDocument) mFactory.createDocument( url.toString() ), width );
  }

  public static Image rasterize(
      final SVGDocument svg, final int width ) throws TranscoderException {
    final var transcoder = new BufferedImageTranscoder();
    final var input = new TranscoderInput( svg );

    transcoder.addTranscodingHint( KEY_BACKGROUND_COLOR, WHITE );
    transcoder.addTranscodingHint( KEY_WIDTH, (float) width );
    transcoder.transcode( input, null );

    return transcoder.getImage();
  }

  @SuppressWarnings("SuspiciousNameCombination")
  private static Image createPlaceholderImage( final int width ) {
    final var image = new BufferedImage( width, width, TYPE_INT_RGB );
    final var graphics = (Graphics2D) image.getGraphics();

    graphics.setColor( RED );
    graphics.setStroke( new BasicStroke( 5 ) );
    graphics.drawOval( 5, 5, width / 2, width / 2 );

    return image;
  }
}