【问题标题】:SVG Salamander example?SVG蝾螈例子?
【发布时间】:2011-01-24 17:53:37
【问题描述】:

我正在玩 Java 和 SVG Salamander,但不知道如何将简单的 SVG 文件渲染成 JPanel

谁能给我一个简单的例子?尝试按照官网的松散教程进行操作,但找不到简单的代码来更好地理解。

【问题讨论】:

    标签: java svg svg-salamander


    【解决方案1】:

    首先,您需要以某种方式创建图表 (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);
    

    【讨论】:

      【解决方案2】:

      存储库有example code。如果您想使用最新的,则涉及几个步骤:

      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,可以像其他任何东西一样对待:

      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();
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-06-12
        • 2018-04-18
        • 2014-11-01
        • 1970-01-01
        • 2016-08-22
        • 2020-12-19
        • 2017-02-13
        • 2014-05-20
        • 1970-01-01
        相关资源
        最近更新 更多