Java と SVG Salamander をいじっていますが、単純な SVG ファイルを .xml ファイルにレンダリングする方法がわかりませんJPanel
。
誰かが私に簡単な例を教えてもらえますか? 公式サイトの緩いチュートリアルに従おうとしましたが、理解を深めるための簡単なコードが見つかりませんでした。
Java と SVG Salamander をいじっていますが、単純な SVG ファイルを .xml ファイルにレンダリングする方法がわかりませんJPanel
。
誰かが私に簡単な例を教えてもらえますか? 公式サイトの緩いチュートリアルに従おうとしましたが、理解を深めるための簡単なコードが見つかりませんでした。
まず、どうにかしてダイアグラム (com.kitfox.svg.SVGDiagram) を作成する必要があります。
File f = new File(mysvgfile);
SVGUniverse svgUniverse = new SVGUniverse();
SVGDiagram diagram = svgUniverse.getDiagram(svgUniverse.loadSVG(f.toURL()));
これで、ファイルをレンダリングする場合 (通常はパネルの paintComponent() メソッドから) を実行するだけで済みます ( g
Graphics2D インスタンスである場合):
diagram.render(g);
そして(いつものように?)、何か変更した方法で描画したい場合:
AffineTransform oldTransform = g.getTransform();
g.scale(...);
g.translate(...);
...
diagram.render(g);
g.setTransform(oldTransform);
リポジトリにはサンプル コードがあります。最新のものを使用する場合は、いくつかの手順が必要です。
Apache Mavenをインストールします。
リポジトリをどこかにクローンします。
mkdir -p $HOME/dev/java/
cd $HOME/dev/java
git clone https://github.com/blackears/svgSalamander
更新pom.xml
:
cd svgSalamander/svg-core
vi pom.xml
source
、target
、および JDKのバージョン番号を変更します。
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<jdkVersion>1.7</jdkVersion>
保存しますpom.xml
。
Maven を使用して JAR ファイルを生成します。mvn package
プログラムのライブラリ ディレクトリ (例: ) にコピーtarget/svgSalamander-1.1.2.jar
します (必ずバージョン番号を変更する必要がありますlibs
)。
プログラムがビルドにGradleを使用している場合は、ローカル JAR ファイルを使用するように依存関係を更新します。
dependencies {
// SVG
implementation fileTree(include: ['**/*.jar'], dir: 'libs')
}
別のビルド システムを使用している場合は、それに応じて依存関係を変更する必要があります。そこから、SVG Salamander を使用してベクター グラフィック リソース ファイルをスケーリングおよびラスタライズするクラスを次に示します。
import com.kitfox.svg.SVGDiagram;
import com.kitfox.svg.SVGException;
import com.kitfox.svg.SVGUniverse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.Map;
import static java.awt.RenderingHints.*;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
/**
* Responsible for converting SVG images into rasterized PNG images.
*/
public class SvgRasterizer {
public final static Map<Object, Object> RENDERING_HINTS = Map.of(
KEY_ANTIALIASING,
VALUE_ANTIALIAS_ON,
KEY_ALPHA_INTERPOLATION,
VALUE_ALPHA_INTERPOLATION_QUALITY,
KEY_COLOR_RENDERING,
VALUE_COLOR_RENDER_QUALITY,
KEY_DITHERING,
VALUE_DITHER_DISABLE,
KEY_FRACTIONALMETRICS,
VALUE_FRACTIONALMETRICS_ON,
KEY_INTERPOLATION,
VALUE_INTERPOLATION_BICUBIC,
KEY_RENDERING,
VALUE_RENDER_QUALITY,
KEY_STROKE_CONTROL,
VALUE_STROKE_PURE,
KEY_TEXT_ANTIALIASING,
VALUE_TEXT_ANTIALIAS_ON
);
private final static SVGUniverse sRenderer = new SVGUniverse();
/**
* Rasterizes a vector graphic to a given size using a {@link BufferedImage}.
* The rendering hints are set to produce high quality output.
*
* @param path Fully qualified path to the image resource to rasterize.
* @param dstDim The output image dimensions.
* @return The rasterized {@link Image}.
* @throws SVGException Could not open, read, parse, or render SVG data.
*/
public Image rasterize( final String path, final Dimension dstDim )
throws SVGException {
final var diagram = loadDiagram( path );
final var wDiagram = diagram.getWidth();
final var hDiagram = diagram.getHeight();
final var srcDim = new Dimension( (int) wDiagram, (int) hDiagram );
final var scaled = fit( srcDim, dstDim );
final var wScaled = (int) scaled.getWidth();
final var hScaled = (int) scaled.getHeight();
final var image = new BufferedImage( wScaled, hScaled, TYPE_INT_ARGB );
final var g = image.createGraphics();
g.setRenderingHints( RENDERING_HINTS );
final var transform = g.getTransform();
transform.setToScale( wScaled / wDiagram, hScaled / hDiagram );
g.setTransform( transform );
diagram.render( g );
g.dispose();
return image;
}
/**
* Gets an instance of {@link URL} that references a file in the
* application's resources.
*
* @param path The full path (starting at the root), relative to the
* application or JAR file's resources directory.
* @return A {@link URL} to the file or {@code null} if the path does not
* point to a resource.
*/
private URL getResourceUrl( final String path ) {
return SvgRasterizer.class.getResource( path );
}
/**
* Loads the resource specified by the given path into an instance of
* {@link SVGDiagram} that can be rasterized into a bitmap format. The
* {@link SVGUniverse} class will
*
* @param path The full path (starting at the root), relative to the
* application or JAR file's resources directory.
* @return An {@link SVGDiagram} that can be rasterized onto a
* {@link BufferedImage}.
*/
private SVGDiagram loadDiagram( final String path ) {
final var url = getResourceUrl( path );
final var uri = sRenderer.loadSVG( url );
final var diagram = sRenderer.getDiagram( uri );
return applySettings( diagram );
}
/**
* Instructs the SVG renderer to rasterize the image even if it would be
* clipped.
*
* @param diagram The {@link SVGDiagram} to render.
* @return The same instance with ignore clip heuristics set to {@code true}.
*/
private SVGDiagram applySettings( final SVGDiagram diagram ) {
diagram.setIgnoringClipHeuristic( true );
return diagram;
}
/**
* Scales the given source {@link Dimension} to the destination
* {@link Dimension}, maintaining the aspect ratio with respect to
* the best fit.
*
* @param src The original vector graphic dimensions to change.
* @param dst The desired image dimensions to scale.
* @return The given source dimensions scaled to the destination dimensions,
* maintaining the aspect ratio.
*/
private Dimension fit( final Dimension src, final Dimension dst ) {
final var srcWidth = src.getWidth();
final var srcHeight = src.getHeight();
// Determine the ratio that will have the best fit.
final var ratio = Math.min(
dst.getWidth() / srcWidth, dst.getHeight() / srcHeight
);
// Scale both dimensions with respect to the best fit ratio.
return new Dimension( (int) (srcWidth * ratio), (int) (srcHeight * ratio) );
}
}
を次のように使用SvgRasterizer
します。
final var rasterizer = new SvgRasterizer();
final var image = rasterizer.rasterize( "/images/icon.svg", new Dimension( 200, 200 ) );
そのイメージは、手間をかけずに Swing コンポーネントに追加できます。たとえば、JComponent
他のものと同じように扱うことができる a は次のとおりです。
import javax.swing.*;
import java.awt.*;
/**
* Responsible for drawing an image, which can be changed at any time.
*/
public class ImageComponent extends JComponent {
/**
* Mutable image.
*/
private Image mImage;
ImageComponent( final Image image ) {
mImage = image;
}
@Override
public Dimension getPreferredSize() {
// Race-condition guard.
final var image = mImage;
return new Dimension(
image.getWidth( null ), image.getHeight( null )
);
}
@Override
protected void paintComponent( final Graphics graphics ) {
super.paintComponent( graphics );
final var g = (Graphics2D) graphics.create();
g.drawImage( mImage, 0, 0, this );
}
/**
* Repaints this component using the given image. This is a mutable
* operation that changes the internal {@link Image} instance.
*
* @param image The new image to use for painting.
*/
public void redraw( final Image image ) {
mImage = image;
repaint();
}
}