LoginSignup
3
3

More than 3 years have passed since last update.

Java + Apache Batik で SVG を編集して PNG や JPEG に変換する

Last updated at Posted at 2020-10-03

概要

  • Java + Apache Batik で SVG を編集して PNG や JPEG に変換して出力する
  • 環境: Apache Batik 1.13 + Java 15 (AdoptOpenJDK 15+36) + Gradle 6.6.1

サンプルコード

build.gradle

Gradle で実行するように記述する。使用するライブラリを記載する。

plugins {
  id 'java'
  id 'application'
}

repositories {
  mavenCentral()
}

dependencies {
  // SVG を他のフォーマットに変換するための Apache Batik のコアモジュール
  implementation 'org.apache.xmlgraphics:batik-transcoder:1.13'

  // PNG や JPEG の出力に必要なモジュール
  runtimeOnly 'org.apache.xmlgraphics:batik-codec:1.13'
}

application {
  mainClassName = 'MyApp'
}

MyApp.java

SVG ファイルを読み込んで編集して PNG, JPEG, SVG で出力する。

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import org.w3c.dom.Element;

// Apache Batik
import org.apache.batik.anim.dom.SAXSVGDocumentFactory;
import org.apache.batik.anim.dom.SVGDOMImplementation;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.JPEGTranscoder;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.batik.transcoder.svg2svg.SVGTranscoder;
import org.apache.batik.util.XMLResourceDescriptor;

// Apache XML Commons External Components XML APIs Extensions (xml-apis-ext)
import org.w3c.dom.svg.SVGDocument;

public class MyApp {

  public static void main(String[] args) throws IOException, TranscoderException {

    // 入力する SVG のファイルパスから URI を構築
    URI inputUri = new File("input.svg").toURI();

    // SVGDocument は org.w3c.dom.Document を extends している interface
    SVGDocument doc = new SAXSVGDocumentFactory(
      XMLResourceDescriptor.getXMLParserClassName())
      .createSVGDocument(inputUri.toString());

    // SVG を編集することも可能
    // ここでは path 要素を追加してみる
    Element path = doc.createElementNS(SVGDOMImplementation.SVG_NAMESPACE_URI, "path");
    path.setAttribute("id", "foo");
    path.setAttribute("d", "M 1000,2000 h 1000 v 1000 h -1000 z"); // 正方形を描く
    path.setAttribute("style", "fill: #ff0000; stroke: #0000ff; stroke-width: 100");
    doc.getFirstChild().appendChild(path);

    // 変換用の入力オブジェクトを生成
    TranscoderInput input = new TranscoderInput(doc);

    // 各種フォーマットで出力する
    outputPng(input, new File("output.png"));
    outputJpg(input, new File("output.jpg"));
    outputSvg(input, new File("output.svg"));
  }

  // PNG で出力する
  private static void outputPng(TranscoderInput input, File outFile) throws IOException, TranscoderException {
    PNGTranscoder t = new PNGTranscoder();
    try (OutputStream os = new FileOutputStream(outFile)) {
      TranscoderOutput output = new TranscoderOutput(os);
      t.transcode(input, output);
    }
  }

  // JPEG で出力する
  private static void outputJpg(TranscoderInput input, File outFile) throws IOException, TranscoderException {
    JPEGTranscoder t = new JPEGTranscoder();
    t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, .8f);
    try (OutputStream os = new FileOutputStream(outFile)) {
      TranscoderOutput output = new TranscoderOutput(os);
      t.transcode(input, output);
    }
  }

  // SVG で出力する
  private static void outputSvg(TranscoderInput input, File outFile) throws IOException, TranscoderException {
    SVGTranscoder t = new SVGTranscoder();
    try (OutputStream os = new FileOutputStream(outFile)) {
      OutputStreamWriter writer = new OutputStreamWriter(os, StandardCharsets.UTF_8);
      TranscoderOutput output = new TranscoderOutput(writer);
      t.transcode(input, output);
    }
  }
}

実行方法

同じディレクトリに任意の入力ファイル input.svg を置いて gradle run で実行。

$ gradle run

参考資料

Apache Batik

Apache XML Commons External Components XML APIs Extensions

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3