簡體   English   中英

使用Apache Batik縮放SVG圖像時如何忽略比例?

[英]How to ignore proportionality when scaling SVG images using Apache Batik?

我目前正在嘗試創建一個自定義JComponent(ViewerComponent),以使用apache batik縮放並顯示SVG圖像。 目前,ViewerComponent會按比例縮放SVG圖像; 但是,我希望它按比例縮放以適合組件的大小,而忽略了比例性。 下面的代碼顯示了我為ViewerComponent編寫的一個簡單測試。 如何將ViewerComponent修改為如上所述的行為?

import java.awt.*;
import java.awt.event.*;
import java.net.*;
import javax.swing.*;
import org.apache.batik.swing.*;
import org.apache.batik.swing.gvt.*;
import org.apache.batik.util.*;
import org.w3c.dom.svg.*;

public final class View extends JPanel {

    public static final Dimension VIEW_SIZE = new Dimension(2000, 2000);
    public static final Dimension WINDOW_SIZE = new Dimension(600, 600);
    public static final String BACKGROUND_IMAGE
            = "file:///Users/home/Desktop/wiki.svg";

    private JScrollPane scrollPane;
    private ViewerComponent canvas;

    View() throws URISyntaxException {
        setUpGUI();
        createViewerBasedOnViewportSize();
    }

    private void setUpGUI() throws HeadlessException {
        setUpView();
        setUpScrollPane();
        setUpFrame();
    }

    private void setUpView() {
        this.setPreferredSize(VIEW_SIZE);
        this.setBackground(Color.WHITE);
    }

    private void setUpScrollPane() {
        scrollPane = new JScrollPane(this);
    }

    private void setUpFrame() throws HeadlessException {
        JFrame frame = new JFrame("SVG Viewer Test");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setContentPane(scrollPane);
        frame.setPreferredSize(WINDOW_SIZE);
        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);
        frame.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                adjustBackgroundComponentScale();
                repaint();
            }
        });
    }

    private void adjustBackgroundComponentScale() {
        if (canvas != null) {
            Dimension windowSize = calculateWindowSize();
            canvas.setFinalViewerSize(windowSize);
        }
    }

    private void createViewerBasedOnViewportSize() throws URISyntaxException {
        Dimension windowSize = calculateWindowSize();
        URI uri = retrieveURI();
        createViewer(uri, windowSize);
    }

    private Dimension calculateWindowSize() {
        final JViewport vp = (JViewport) getParent();
        final Dimension windowSize = vp.getVisibleRect().getSize();
        return windowSize;
    }

    private URI retrieveURI() throws URISyntaxException {
        URI uri = new URI(BACKGROUND_IMAGE);
        return uri;
    }

    void createViewer(final URI uri,
            final Dimension preferredSize) {
        canvas = new ViewerComponent(uri);
        canvas.addGVTTreeRendererListener(new GVTTreeRendererAdapter() {
            @Override
            public void gvtRenderingCompleted(final GVTTreeRendererEvent e) {
                canvas.setFinalViewerSize(preferredSize);
                canvas.revalidate();
                canvas.removeGVTTreeRendererListener(this);
            }
        });
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (canvas != null) {
            setAndPaintViewer(g);
        }
    }

    private void setAndPaintViewer(Graphics g) {
        Graphics backgroundGraphics = g.create();
        try {
            setBackgroundComponentLocation(backgroundGraphics);
            canvas.paint(backgroundGraphics);
            repaint();
        } finally {
            backgroundGraphics.dispose();
        }
    }

    private void setBackgroundComponentLocation(Graphics g) {
        final JViewport vp = (JViewport) getParent();
        final Point viewPosition = vp.getViewPosition();
        g.translate(viewPosition.x, viewPosition.y);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    new View();
                } catch (URISyntaxException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

}

class ViewerComponent extends JSVGCanvas {

    private static final long serialVersionUID = 1L;
    private Dimension originalSize = null;

    public Dimension getOriginalSize() {
        return new Dimension(originalSize);
    }

    public void setFinalViewerSize(final Dimension size) {
        final JSVGCanvas canvas = this;
        canvas.setPreferredSize(size);
        canvas.setMySize(size);
        canvas.setSize(size);
    }

    public void setDraftViewerSize(final Dimension size) {
        setFinalViewerSize(size);
    }

    public void setFinalViewerSize(final float zoom) {
        int scaledWidth = (int) (originalSize.width * zoom);
        int scaledHeight = (int) (originalSize.height * zoom);
        setFinalViewerSize(new Dimension(scaledWidth, scaledHeight));
    }

    public ViewerComponent(final URI uri) {
        super(null, false, false);
        setDocumentState(ALWAYS_STATIC);
        setSize(1, 1);
        setRecenterOnResize(true);
        addGVTTreeRendererListener(new GVTTreeRendererAdapter() {
            @Override
            public void gvtRenderingStarted(final GVTTreeRendererEvent e) {
                super.gvtRenderingStarted(e);
                final SVGDocument document = getSVGDocument();
                final SVGSVGElement rootElement = document.getRootElement();
                final SVGLength width = rootElement.getWidth().getBaseVal();
                final SVGLength height = rootElement.getHeight()
                        .getBaseVal();
                float defaultWidth = (float) Math.ceil(width.getValue());
                float defaultHeigth = (float) Math.ceil(height.getValue());
                if (defaultWidth == 1f && defaultHeigth == 1f) {
                    defaultWidth = 200;
                    defaultHeigth = 200;
                }
                originalSize = new Dimension((int) defaultWidth,
                        (int) defaultHeigth);
                if ("".equals(rootElement.getAttributeNS(null,
                        SVGConstants.SVG_VIEW_BOX_ATTRIBUTE))) {
                    rootElement.setAttributeNS(null,
                            SVGConstants.SVG_VIEW_BOX_ATTRIBUTE, "0 0 "
                            + defaultWidth + " " + defaultHeigth);
                }
                setSize(originalSize);
                removeGVTTreeRendererListener(this);
            }
        });
        setURI(uri.toString());
    }

    @Override
    public Dimension getPreferredSize() {
        if (originalSize == null) {
            return new Dimension(1, 1);
        }
        return super.getPreferredSize();
    }

}

您需要將preserveAspectRatio屬性設置為none 因此,它將類似於:

rootElement.setAttribute("preserveAspectRatio", "none");

我本人並沒有以這種方式使用蠟染庫,但這是實現此結果的DOM方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM