简体   繁体   English

加载 SVG 图像所需的蜡染罐

[英]Required batik jars for loading SVG images

I use the batik-transcoder to read SVG files and transform them to BufferedImage.我使用蜡染转码器读取 SVG 文件并将它们转换为 BufferedImage。 My problem is, that maven downloads about 19 another jars to compile my code.我的问题是,maven 下载了大约 19 个 jar 来编译我的代码。 Which jars are required for my use case?我的用例需要哪些罐子?

The list of jars which are downloaded by maven is: maven 下载的 jars 列表是:

[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

PS Suggestions about another SVG libs are also welcome. PS 也欢迎关于另一个 SVG 库的建议。 I've already seen the SVGSalamander.我已经看过SVGSalamander了。 It allows what I want but it don't looks like a good designed and good supported lib (IMHO).它允许我想要的东西,但它看起来不像是一个设计良好且支持良好的库(恕我直言)。

If using gradle, the minimal dependencies can be included using:如果使用 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 suggests essentially the same collection when deploying reports to a server. JasperReports 5.0 在将报告部署到服务器时建议使用基本相同的集合。 The difference is that batik-transcoder (relatively new?) isn't on their list (though I imagine it is required for later versions of JasperReports):不同之处在于 batik-transcoder(相对较新?)不在他们的列表中(尽管我认为 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

To get everything:得到一切:

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

Change the version number as necessary.根据需要更改版本号。

Note: I've only tested this against two SVG illustrations.注意:我只针对两个 SVG 插图进行了测试。 Both rendered flawlessly.两者都完美呈现。 There could be some dependencies that aren't required (such as batik-anim ) depending on your requirements.根据您的要求,可能有一些不需要的依赖项(例如batik-anim )。


SVG Salamander is another SVG Engine. SVG Salamander是另一个 SVG 引擎。 Lighter than Batik, it isn't as robust.它比蜡染轻,但没有那么坚固。 Note that Batik cannot handle textual flowRoot elements easily and may result in black boxes.请注意,Batik 无法轻松处理文本flowRoot元素,并且可能会导致黑框。 Eliminating the black boxes requires removing all flowRoot elements, which can take some time.消除黑盒需要移除所有flowRoot元素,这可能需要一些时间。 (The other possibility is to perform an XSL transformation on the SVG file to fix the flowRoot issue, but that approach probably won't address all the issues encountered.) (另一种可能性是对 SVG 文件执行 XSL 转换以修复flowRoot问题,但这种方法可能无法解决遇到的所有问题。)


Here's an example SVGRasterizer class that builds and works with the aforementioned subset of Batik library files:这是一个示例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;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM