杰瑞科技汇

Java如何实现SVG转PNG?

Of course! Converting SVG (Scalable Vector Graphics) to PNG (Portable Network Graphics) in Java is a common task. The key is to use a library that can render the vector-based SVG into a raster-based PNG image.

Java如何实现SVG转PNG?-图1
(图片来源网络,侵删)

There are two excellent and popular libraries for this:

  1. Apache Batik: The most powerful and feature-rich library. It's a complete toolkit for SVG. It's heavier but gives you maximum control.
  2. Harmonic-svg: A much simpler and more modern library. It's lightweight, easy to use, and focuses specifically on rendering SVGs to Java's Image objects.

I'll show you how to use both, starting with the simpler one.


Method 1: Using Harmonic-svg (Recommended for Simplicity)

This is the quickest and easiest way to get a basic conversion done. It's perfect for most use cases.

Step 1: Add the Dependency

Add the harmonic-svg dependency to your project. If you're using Maven, add this to your pom.xml:

Java如何实现SVG转PNG?-图2
(图片来源网络,侵删)
<dependency>
    <groupId>io.github.humbleui</groupId>
    <artifactId>harmonic-svg</artifactId>
    <version>0.1.0</version> <!-- Check for the latest version -->
</dependency>

Step 2: Write the Java Code

The process is straightforward: load the SVG, create a BufferedImage, and then render the SVG onto it.

import io.github.humbleui.jwm.*;
import io.github.humbleui.jwm.skia.SkiaSurface;
import io.github.humbleui.types.Point;
import org.jetbrains.skija.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
public class SvgToPngHarmonic {
    public static void main(String[] args) {
        // 1. Define the output PNG file path
        File outputFile = new File("output.png");
        // 2. Define the desired PNG dimensions (width and height in pixels)
        int pngWidth = 800;
        int pngHeight = 600;
        // 3. Read the SVG content from a file or a string
        // Here, we'll use a simple SVG string for demonstration
        String svgContent = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"200\" height=\"200\" viewBox=\"0 0 200 200\">\n" +
                "  <circle cx=\"100\" cy=\"100\" r=\"80\" fill=\"green\" />\n" +
                "  <text x=\"100\" y=\"110\" font-family=\"Verdana\" font-size=\"20\" text-anchor=\"middle\" fill=\"white\">Hello SVG!</text>\n" +
                "</svg>";
        try {
            // 4. Create a BufferedImage for the output
            // We use the Skia backend from JWM for high-quality rendering
            var surface = SkiaSurface.makeRaster(pngWidth, pngHeight);
            var canvas = surface.getCanvas();
            // 5. Render the SVG onto the canvas
            // The second parameter (Point) is for offset (x, y). We'll use (0, 0).
            // The third parameter is the viewport size (width, height).
            SVG svg = SVG.makeFromString(svgContent);
            svg.draw(canvas, new Point(0, 0), new IRect(0, 0, pngWidth, pngHeight));
            // 6. Encode the image as PNG and save it to the file
            Image image = surface.makeImageSnapshot();
            Data pngData = image.encodeToData(EncodedImageFormat.PNG);
            Files.write(outputFile.toPath(), pngData.toBytes());
            System.out.println("Successfully converted SVG to PNG: " + outputFile.getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

To run this, you also need the JWM dependencies for Skia. Add these to your pom.xml as well:

<dependency>
    <groupId>io.github.humbleui</groupId>
    <artifactId>jwm</artifactId>
    <version>0.3.5</version> <!-- Check for the latest version -->
</dependency>
<dependency>
    <groupId>io.github.humbleui</groupId>
    <artifactId>jwm-skia</artifactId>
    <version>0.3.5</version>
</dependency>

Method 2: Using Apache Batik (More Powerful & Flexible)

Batik is a full-fledged SVG toolkit. It's great if you need advanced features like CSS support, scripting, or more granular control over the rendering process.

Step 1: Add the Dependencies

Batik has several modules. For basic conversion, you'll need the core, transcoder, and util modules.

Java如何实现SVG转PNG?-图3
(图片来源网络,侵删)
<dependencies>
    <!-- Batik Core -->
    <dependency>
        <groupId>org.apache.xmlgraphics</groupId>
        <artifactId>batik-transcoder</artifactId>
        <version>1.14</version> <!-- Check for the latest version -->
    </dependency>
    <dependency>
        <groupId>org.apache.xmlgraphics</groupId>
        <artifactId>batik-util</artifactId>
        <version>1.14</version>
    </dependency>
    <!-- You might also need this for some image I/O -->
    <dependency>
        <groupId>org.apache.xmlgraphics</groupId>
        <artifactId>batik-xml</artifactId>
        <version>1.14</version>
    </dependency>
</dependencies>

Step 2: Write the Java Code

Batik uses a "transcoder" pattern, which is a clean way to convert between formats.

import org.apache.batik.transcoder.Transcoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class SvgToPngBatik {
    public static void main(String[] args) {
        // 1. Define input and output files
        File svgFile = new File("input.svg");
        File pngFile = new File("output_batik.png");
        // 2. Define the desired PNG dimensions
        float pngWidth = 800;
        float pngHeight = 600;
        try {
            // 3. Create a PNGTranscoder
            Transcoder transcoder = new PNGTranscoder();
            // 4. Set the transcoding hints (dimensions)
            transcoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, pngWidth);
            transcoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, pngHeight);
            // 5. Create a TranscoderInput from the SVG file
            // You can also use a URI: new TranscoderInput(svgFile.toURI().toString());
            TranscoderInput input = new TranscoderInput(svgFile.toURI().toString());
            // 6. Create a TranscoderOutput to the FileOutputStream
            try (OutputStream ostream = new FileOutputStream(pngFile)) {
                TranscoderOutput output = new TranscoderOutput(ostream);
                // 7. Perform the conversion
                System.out.println("Starting conversion...");
                transcoder.transcode(input, output);
                System.out.println("Conversion complete!");
            }
            System.out.println("Successfully converted SVG to PNG: " + pngFile.getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

To use this example, you'll need an input.svg file in your project's root directory.


Comparison and Recommendation

Feature Harmonic-svg Apache Batik
Ease of Use Excellent. Very simple API. Good. API is logical but requires more setup.
Dependencies Lightweight (JWM + Harmonic). Heavier (multiple XMLGraphics modules).
Features Focused on rendering SVGs to images. Full SVG toolkit: CSS, scripting, DOM manipulation.
Quality Excellent (uses Skia). Excellent (industry-standard).
Use Case Quick conversions, simple SVGs, modern apps. Complex SVGs, need for CSS/JS support, server-side processing.

Recommendation:

  • For most developers who just need to convert an SVG to a PNG image, use Harmonic-svg. It's modern, easy, and gets the job done efficiently.
  • If you are working with very complex SVGs that rely on CSS styles or embedded JavaScript, or if you need to inspect and manipulate the SVG document before converting, use Apache Batik. It's the more robust and complete solution.
分享:
扫描分享到社交APP
上一篇
下一篇