7

Java と SVG Salamander をいじっていますが、単純な SVG ファイルを .xml ファイルにレンダリングする方法がわかりませんJPanel

誰かが私に簡単な例を教えてもらえますか? 公式サイトの緩いチュートリアルに従おうとしましたが、理解を深めるための簡単なコードが見つかりませんでした。

4

2 に答える 2

7

まず、どうにかしてダイアグラム (com.kitfox.svg.SVGDiagram) を作成する必要があります。

File f = new File(mysvgfile);
SVGUniverse svgUniverse = new SVGUniverse();
SVGDiagram diagram = svgUniverse.getDiagram(svgUniverse.loadSVG(f.toURL()));

これで、ファイルをレンダリングする場合 (通常はパネルの paintComponent() メソッドから) を実行するだけで済みます ( gGraphics2D インスタンスである場合):

diagram.render(g);

そして(いつものように?)、何か変更した方法で描画したい場合:

AffineTransform oldTransform = g.getTransform();
g.scale(...);
g.translate(...);
...
diagram.render(g);
g.setTransform(oldTransform);
于 2010-04-09T13:00:33.730 に答える
4

リポジトリにはサンプル コードがあります。最新のものを使用する場合は、いくつかの手順が必要です。

  1. Apache Mavenをインストールします。

  2. リポジトリをどこかにクローンします。

    mkdir -p $HOME/dev/java/
    cd $HOME/dev/java
    git clone https://github.com/blackears/svgSalamander
    
  3. 更新pom.xml

    cd svgSalamander/svg-core
    vi pom.xml
    
  4. sourcetarget、および JDKのバージョン番号を変更します。

    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    
    <jdkVersion>1.7</jdkVersion>
    
  5. 保存しますpom.xml

  6. Maven を使用して JAR ファイルを生成します。mvn package

  7. プログラムのライブラリ ディレクトリ (例: ) にコピー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();
  }
}
于 2010-03-13T08:59:09.173 に答える