2014-09-24 28 views
10

Arkaplan

okunmasına ilişkin cevaplanmamış soru sayısının ve ayrıştırma SVG yolları vardır:yüklemek ve ayrıştırmak nasıl SVG belgeler

Bu soru ve cevap, tüm bu soruları çözmeyi amaçlamaktadır.

sorun

path elemanı data attribute (d) içeren SVG. Bazen bir SVG dosyasından yol bilgisini yüklemek, ayrıştırmak ve ayıklamak gerekir.

Soru

nasıl ayrıştırmak, yük ve Java kullanarak SVG dosyasından SVG yol bilgilerini ayıklamak? Apache Batik kullanarak

cevap

11

Bakış

yükleyin ve ayrıştırmak SVG dosyaları. Çözüm, bir SVG dosyasının MetaPost'a dönüştürülmesinin ön aşamalarında Java kodunu gösterir. Bu, Java kullanarak SVG dosyalarından içeriğin nasıl yükleneceği, ayrıştırılacağı ve ayıklanacağı konusunda genel bir fikir vermelidir.

Kütüphaneler

Aşağıdaki kütüphaneleri gerekir:

batik-anim.jar 
batik-awt-util.jar 
batik-bridge.jar 
batik-css.jar 
batik-dom.jar 
batik-ext.jar 
batik-gvt.jar 
batik-parser.jar 
batik-script.jar 
batik-svg-dom.jar 
batik-svggen.jar 
batik-util.jar 
batik-xml.jar 
xml-apis-ext.jar 

Yük SVG Dosya

ana uygulama DOM'ye SVG dosyasını yükler, sonra bir SVG DOM DOM dönüştürür. initSVGDOM() yöntem çağrısı son derece önemlidir. initSVGDOM() numaralı telefonu aramadan, DOM'dan SVG DOM öğelerini ayıklama yöntemleri kullanılamaz.

import java.io.File; 
import java.io.IOException; 

import java.net.URI; 

import org.apache.batik.bridge.BridgeContext; 
import org.apache.batik.bridge.DocumentLoader; 
import org.apache.batik.bridge.GVTBuilder; 
import org.apache.batik.bridge.UserAgent; 
import org.apache.batik.bridge.UserAgentAdapter; 
import org.apache.batik.dom.svg.SAXSVGDocumentFactory; 
import org.apache.batik.dom.svg.SVGOMSVGElement; 
import org.apache.batik.util.XMLResourceDescriptor; 

import org.w3c.dom.Document; 
import org.w3c.dom.NodeList; 


/** 
* Responsible for converting all SVG path elements into MetaPost curves. 
*/ 
public class SVGMetaPost { 
    private static final String PATH_ELEMENT_NAME = "path"; 

    private Document svgDocument; 

    /** 
    * Creates an SVG Document given a URI. 
    * 
    * @param uri Path to the file. 
    * @throws Exception Something went wrong parsing the SVG file. 
    */ 
    public SVGMetaPost(String uri) throws IOException { 
    setSVGDocument(createSVGDocument(uri)); 
    } 

    /** 
    * Finds all the path nodes and converts them to MetaPost code. 
    */ 
    public void run() { 
    NodeList pathNodes = getPathElements(); 
    int pathNodeCount = pathNodes.getLength(); 

    for(int iPathNode = 0; iPathNode < pathNodeCount; iPathNode++) { 
     MetaPostPath mpp = new MetaPostPath(pathNodes.item(iPathNode)); 
     System.out.println(mpp.toCode()); 
    } 
    } 

    /** 
    * Returns a list of elements in the SVG document with names that 
    * match PATH_ELEMENT_NAME. 
    * 
    * @return The list of "path" elements in the SVG document. 
    */ 
    private NodeList getPathElements() { 
    return getSVGDocumentRoot().getElementsByTagName(PATH_ELEMENT_NAME); 
    } 

    /** 
    * Returns an SVGOMSVGElement that is the document's root element. 
    * 
    * @return The SVG document typecast into an SVGOMSVGElement. 
    */ 
    private SVGOMSVGElement getSVGDocumentRoot() { 
    return (SVGOMSVGElement)getSVGDocument().getDocumentElement(); 
    } 

    /** 
    * This will set the document to parse. This method also initializes 
    * the SVG DOM enhancements, which are necessary to perform SVG and CSS 
    * manipulations. The initialization is also required to extract information 
    * from the SVG path elements. 
    * 
    * @param document The document that contains SVG content. 
    */ 
    public void setSVGDocument(Document document) { 
    initSVGDOM(document); 
    this.svgDocument = document; 
    } 

    /** 
    * Returns the SVG document parsed upon instantiating this class. 
    * 
    * @return A valid, parsed, non-null SVG document instance. 
    */ 
    public Document getSVGDocument() { 
    return this.svgDocument; 
    } 

    /** 
    * Enhance the SVG DOM for the given document to provide CSS- and SVG-specific 
    * DOM interfaces. 
    * 
    * @param document The document to enhance. 
    * @link http://wiki.apache.org/xmlgraphics-batik/BootSvgAndCssDom 
    */ 
    private void initSVGDOM(Document document) { 
    UserAgent userAgent = new UserAgentAdapter(); 
    DocumentLoader loader = new DocumentLoader(userAgent); 
    BridgeContext bridgeContext = new BridgeContext(userAgent, loader); 
    bridgeContext.setDynamicState(BridgeContext.DYNAMIC); 

    // Enable CSS- and SVG-specific enhancements. 
    (new GVTBuilder()).build(bridgeContext, document); 
    } 

    /** 
    * Use the SAXSVGDocumentFactory to parse the given URI into a DOM. 
    * 
    * @param uri The path to the SVG file to read. 
    * @return A Document instance that represents the SVG file. 
    * @throws Exception The file could not be read. 
    */ 
    private Document createSVGDocument(String uri) throws IOException { 
    String parser = XMLResourceDescriptor.getXMLParserClassName(); 
    SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser); 
    return factory.createDocument(uri); 
    } 

    /** 
    * Reads a file and parses the path elements. 
    * 
    * @param args args[0] - Filename to parse. 
    * @throws IOException Error reading the SVG file. 
    */ 
    public static void main(String args[]) throws IOException { 
    URI uri = new File(args[0]).toURI(); 
    SVGMetaPost converter = new SVGMetaPost(uri.toString()); 
    converter.run(); 
    } 
} 

Not: Aksi belirtilmedikçe initSVGDOM() çağrılması Batik varsayılan davranışı olmalıdır. Ne yazık ki, değil, ve bu gem keşfetme kendi web sitesinde documentation buried okuma anlamına gelir. SVG DOM Ayrıştırma Ayrıştırma SVG DOM

sonra nispeten basittir.

import org.apache.batik.dom.svg.SVGItem; 
import org.apache.batik.dom.svg.SVGOMPathElement; 

import org.w3c.dom.Node; 
import org.w3c.dom.svg.SVGPathSegList; 

/** 
* Responsible for converting an SVG path element to MetaPost. This 
* will convert just the bezier curve portion of the path element, not 
* its style. Typically the SVG path data is provided from the "d" attribute 
* of an SVG path node. 
*/ 
public class MetaPostPath extends MetaPost { 
    private SVGOMPathElement pathElement; 

    /** 
    * Use to create an instance of a class that can parse an SVG path 
    * element to produce MetaPost code. 
    * 
    * @param pathNode The path node containing a "d" attribute (output as MetaPost code). 
    */ 
    public MetaPostPath(Node pathNode) { 
    setPathNode(pathNode); 
    } 

    /** 
    * Converts this object's SVG path to a MetaPost draw statement. 
    * 
    * @return A string that represents the MetaPost code for a path element. 
    */ 
    public String toCode() { 
    StringBuilder sb = new StringBuilder(16384); 
    SVGOMPathElement pathElement = getPathElement(); 
    SVGPathSegList pathList = pathElement.getNormalizedPathSegList(); 

    int pathObjects = pathList.getNumberOfItems(); 

    sb.append((new MetaPostComment(getId())).toString()); 

    for(int i = 0; i < pathObjects; i++) { 
     SVGItem item = (SVGItem)pathList.getItem(i); 
     sb.append(String.format("%s%n", item.getValueAsString())); 
    } 

    return sb.toString(); 
    } 

    /** 
    * Returns the value for the id attribute of the path element. If the 
    * id isn't present, this will probably throw a NullPointerException. 
    * 
    * @return A non-null, but possibly empty String. 
    */ 
    private String getId() { 
    return getPathElement().getAttributes().getNamedItem("id").getNodeValue(); 
    } 

    /** 
    * Typecasts the given pathNode to an SVGOMPathElement for later analysis. 
    * 
    * @param pathNode The path element that contains curves, lines, and other 
    * SVG instructions. 
    */ 
    private void setPathNode(Node pathNode) { 
    this.pathElement = (SVGOMPathElement)pathNode; 
    } 

    /** 
    * Returns an SVG document element that contains path instructions (usually 
    * for drawing on a canvas). 
    * 
    * @return An object that contains a list of items representing pen 
    * movements. 
    */ 
    private SVGOMPathElement getPathElement() { 
    return this.pathElement; 
    } 
} 

Yapı ortamına ortamdan değişir

Derleme: toCode() yöntem sınıfının beygir. aşağıdakine benzer bir komut dosyası yardımcı olacaktır:

#!/bin/bash 
mkdir -p ./build 
javac -cp ./lib/* -d ./build ./source/*.java 

./lib dizine tüm .jar dosyaları koymak emin olun.Kaynak dosyaları ./source dizinine koyun.

Run

programı çalıştırmak için bir komut dosyası (veya toplu iş dosyası) oluşturun: Geçerli bir SVG yolunu içeren bir dosya karşı çalıştırdığınızda

#!/bin/bash 
java -cp ./lib/*:./build SVGMetaPost $1 

Çıktı

, bu üretir

:

$ ./run.sh stripe/trigon.svg 
% path8078-6 
M 864.1712 779.3069 
C 864.1712 779.3069 868.04065 815.6211 871.4032 833.4621 
C 873.4048 844.08203 874.91724 855.0544 879.0846 864.82227 
C 884.24023 876.9065 895.2377 887.9899 900.0184 897.3661 
C 904.7991 906.7422 907.3466 918.3257 907.3466 918.3257 
C 907.3466 918.3257 892.80817 887.6536 864.1712 887.3086 
C 835.53424 886.9637 820.9958 918.3257 820.9958 918.3257 
C 820.9958 918.3257 823.6176 906.59644 828.32404 897.3661 
C 833.0304 888.1356 844.10223 876.9065 849.2578 864.82227 
C 853.4252 855.05444 854.9376 844.08203 856.93915 833.4621 
C 860.3017 815.6211 864.17114 779.3069 864.17114 779.3069 
z 

Buradan SVG yol verilerinin düzeltmelerine nasıl okunacakları açık olmalıdır. Java kullanarak SVG nesnelerini yanıtlama. en basit yolu MetaPost SVG dönüştüğünde bu

Ek

Not:

  1. dönüştürme PDF SVG (örneğin, Inkscape veya rsvg-convert kullanılarak).
  2. PDF'yi MetaPost'a pstoedit kullanarak dönüştürün.