Batik Java - JSVGCanvas Gradient无法渲染?

时间:2014-11-22 03:10:14

标签: java svg batik

我正在创建一个小程序,它将根据我选择的选项制作SVG文件。我遇到的问题是JSVGCanvas(来自Batik)似乎不会呈现所做的渐变(使用DOM api)。奇怪的是,如果我导出文件并在Inkscape或测试类here中打开它,它(渐变)渲染!以下是我认为可能很重要的所有信息:

蜡染版:1.7

渐变构建代码:

public Element parse(Document doc, String id) { //This is inside a gradient object.
    Element defs = doc.createElementNS(Main.svgNS, "defs"); //Since multiple defs work in an SVG (or at least Inkscape), I add a defs tag per set of gradients.
    defs.setAttribute("id", id); //Sets the id of the defs tag.

    for (JsonElement je : json.getAsJsonArray("Linears")) { //I use GSON to store data, I am iterating through all objects in the Linears array.
        if (je.isJsonObject()) { //Just a type check.
            JsonObject jo = je.getAsJsonObject(); 
            Element lin = doc.createElementNS(Main.svgNS, "linearGradient"); //Creates the linearGradient element.

            for (Entry<String, JsonElement> entry : jo.entrySet()) { //For all elements other than Stops (it is an array) we want to set the attribute.
                if (!entry.getKey().equals("Stops")) {
                    lin.setAttribute(entry.getKey(), entry.getValue().getAsJsonPrimitive().getAsString());
                }
            }

            for (JsonElement stop : jo.getAsJsonArray("Stops")) { //For all objects in stops we want to add a stop.
                Element el = doc.createElementNS(Main.svgNS, "stop"); //Creates a stop element.
                for (Entry<String, JsonElement> entry : stop.getAsJsonObject().entrySet()) {
                    if (entry.getValue().isJsonObject()) {
                        el.setAttribute(entry.getKey(), parseObject(entry.getValue().getAsJsonObject())); //The parseObject method makes a string based on the JsonObject (this is used to get "variables" such as colors).
                    } else {
                        el.setAttribute(entry.getKey(), entry.getValue().getAsString());
                    }
                }
                lin.appendChild(el); //Add stop to the linear gradient.
            }

            defs.appendChild(lin); //Add the linear gradient to defs.
        }
    }

    for (JsonElement je : json.getAsJsonArray("Radials")) { //Loops through all the radial gradients.
        if (je.isJsonObject()) { //Type check.
            JsonObject jo = je.getAsJsonObject();
            Element rad = doc.createElementNS(Main.svgNS, "radialGradient"); //Creates the radialGradient element.

            for (Entry<String, JsonElement> entry : jo.entrySet()) {
                 if (entry.getValue().isJsonPrimitive()) {
                      rad.setAttribute(entry.getKey(), entry.getValue().getAsJsonPrimitive().getAsString());
                 } else {
                      rad.setAttribute(entry.getKey(), parseObject(entry.getValue().getAsJsonObject()));
                 }
            }

            defs.appendChild(rad); //Adds the radial gradient to defs.
        }
    }

    cache = defs;
    return cache; //We return the defs to be added in the main build code.
}

文件创作: 构造:

impl = SVGDOMImplementation.getDOMImplementation();

构建方法:

doc = (SVGDocument) impl.createDocument(svgNS, "svg", null);

JSVGCanvas创作:

preview = new JSVGCanvas();
preview.setEnableImageZoomInteractor(true);
preview.setEnablePanInteractor(true);

以下是我的模板文件的渐变部分(JSON):

"Gradients": {
"Radials": [
  {
    "gradientTransform": "matrix(0.96774313,-1.5022501e-7,3.5488612e-7,1.483871,-201.69415,-217.84922)",
    "inkscape:collect": "always",
    "xmlns:xlink": "http://www.w3.org/1999/xlink",
    "id": "radialGradient5607",
    "gradientUnits": "userSpaceOnUse",
    "xlink:show": "other",
    "xlink:type": "simple",
    "r": "15.5",
    "cx":{
        pre:"",
        var:"X",
        add:327,
        post:""
    },
    "fx":{
        pre:"",
        var:"Y",
        add:327,
        post:""
    },
    "cy": {
        pre:"",
        var:"X",
        add:209,
        post:""
    },
    "fy": {
        pre:"",
        var:"Y",
        add:209,
        post:""
    },
    "xlink:href": "#linearGradient4114",
    "xlink:actuate": "onLoad"
  }
],
"Linears": [
  {
    "xlink:actuate": "onLoad",
    "xlink:type": "simple",
    "id": "linearGradient4114",
    "xlink:show": "other",
    "xmlns:xlink": "http://www.w3.org/1999/xlink",
    "Stops": [
      {
        "offset": "0",
        "style": {
          "pre": "stop-color:",
          "var": "Eye",
          "post": ";stop-opacity:1;"
        },
        "id": "stop4116"
      },
      {
        "style": {
          "pre": "stop-color:",
          "var": "Eye2",
          "post": ";stop-opacity:1;"
        },
        "offset": "0.5",
        "id": "stop4122"
      },
      {
        "offset": "1",
        "style": {
          "pre": "stop-color:",
          "var": "Eye3",
          "post": ";stop-opacity:1;"
        },
        "id": "stop4118"
      }
    ]
  }
]
}

配置文件的那部分然后变成:

<defs id="defs0">
<linearGradient 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    xlink:type="simple" 
    xlink:actuate="onLoad" 
    id="linearGradient4114" 
    xlink:show="other">
    <stop 
        style="stop-color:#d80a00;stop-opacity:1;" 
        offset="0" 
        id="stop4116"/>
    <stop 
        style="stop-color:#ffffff;stop-opacity:1;" 
        offset="0.5"
        id="stop4122"/>
    <stop 
        style="stop-color:#ffffff;stop-opacity:1;" 
        offset="1" 
        id="stop4118"/>
</linearGradient>
<radialGradient 
    gradientTransform="matrix(0.96774313,-1.5022501e-7,3.5488612e-7,1.483871,-201.69415,-217.84922)" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    xlink:type="simple" 
    xlink:href="#linearGradient4114" 
    id="radialGradient5607" 
    xlink:show="other" 
    gradientUnits="userSpaceOnUse" 
    r="15.5" 
    xlink:actuate="onLoad" 
    cx="392.0" 
    fx="427.0" 
    cy="274.0" 
    fy="309.0" 
    inkscape:collect="always"/>

我认为这是名称空间(我不太懂XML / SVG)。我假设这是因为我之前遇到过这样的错误,它在预览中不起作用,但在导出(并加载svg文件)后它会起作用。请注意,这是一个快速的家庭应用程序,因此代码不是最好的(也不是设计),但它适用于我正在做的事情。另请注意,我没有手动输入这些配置文件(这将是疯狂的),我有一个转换器将svg文件转换为这些配置(是的,它听起来像来回走动,但我将这些配置中的多个组合起来制作一个图像)。

1 个答案:

答案 0 :(得分:0)

我昨天和今天搞砸了我。 xlink:href属性要求您将其名称空间设置为xlink&#39; s。对于我的项目意味着这样做:

if (entry.getKey().equals("xlink:href")) {
      rad.setAttributeNS(XMLConstants.XLINK_NAMESPACE_URI, "xlink:href", entry.getValue().getAsJsonPrimitive().getAsString());
}

添加之后,我的渐变成功。