使用Java(桌面)从网站保存SVG图像

时间:2016-07-04 13:08:35

标签: javascript java svg javax.script identicon

我正在使用此代码生成一个JDenticon的网站( test.html ):

<!DOCTYPE HTML>

<html>
    <head>
        <title>Test</title>
    </head>
    <body>
        <script src="https://cdn.jsdelivr.net/jdenticon/1.3.2/jdenticon.min.js" async></script>

        <svg width="200" height="200" data-jdenticon-hash="ff8adece0631821959f443c9d956fc39">
        Fallback text for browsers not supporting inline svg</svg>

    </body>
</html>

我想让这个代码中生成的图像可供Java桌面应用程序访问,并希望将其保存在我的PC上。这是可能的,也许还可以更改hascode( ff8adece0631821959f443c9d956fc39

它的代码是什么?

  

编辑#1:

我在JDenticon的API中找到了类似这样的东西并用于.NET Framework:

var engine = new Jurassic.ScriptEngine();
engine.ExecuteFile("<path to jdenticon.js>");
engine.SetGlobalValue("size", 200);
engine.SetGlobalValue("hash", "ff8adece0631821959f443c9d956fc39");

var svg = engine.Evaluate<string>("jdenticon.toSvg(hash, size)");
File.WriteAllText("testicon.svg", svg);

我想在Java中做这样的事情并找到 Java ScriptEngine (教程:Oracle)。但我不知道如何使用它,现在我的代码看起来像这样:

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");

engine.put("size", 200);
engine.put("hash", "ff8adece0631821959f443c9d956fc39");

String svg = (String) engine.eval(new java.io.FileReader("C:/jdenticon.js"));

这显然不起作用,因为它不会在jdenticon.js文件中调用 jdenticon.toSvg(hash,size)方法。所以,如果有人知道如何解决这个问题,那将是非常好的。

1 个答案:

答案 0 :(得分:2)

您的更新问题包括在JavaScript解释器中运行原始代码的有趣想法,该解释器显然内置于Java SE中,这使我进一步追求该方法,从而生成以下代码,我已经过测试以生成SVG文档文本,至少在我的计算机上生成预期的SVG图标图像。

import java.io.FileNotFoundException;
import java.io.FileReader;
import javax.script.*;

public class JDenticonClient {
    public static void main(String args[]) throws FileNotFoundException, ScriptException {
        String svgText = new JDenticonClient().getSVGDocumentText("ff8adece0631821959f443c9d956fc39", 200);
        System.out.print(svgText);
    }
    public String getSVGDocumentText(String hash, int size) throws FileNotFoundException, ScriptException {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine scriptEngine = factory.getEngineByName("JavaScript");
        scriptEngine.eval(new FileReader("jdenticon.min.js"));
        return scriptEngine.eval("jdenticon.toSvg(\"" + hash + "\", \"" + size + "\")").toString();
    }
}

即使我们采用了相同的解决方案,您也必须考虑以下因素:

  1. put方法将其他脚本宿主对象公开给正在评估的脚本。这基本上是使用带有自定义主机的脚本引擎的整个点,该自定义主机不是具有特定API或Node.js的Web浏览器或类似的东西。基本上,您可以使用put模拟现有API创建自己的API - 是的,甚至复制整个浏览器API集,使您的应用程序成为兼容现代浏览器的脚本主机。 / LI>
  2. 我自己编写了评估过的字符串,但这是一个技术性 - 将原生hashsize分别作为Stringint对象暴露给脚本使用{ {1}}也会起作用,但是你会把那些作为全局变量,这并不总是一件明智的事情,考虑到这些是put过程的自然一次性参数。
  3. 即使您正确地包含了JDenticon脚本评估,您可能还没有考虑到默认情况下,仅包括(并运行)脚本只需调用查找toSvg和{jdenticon的{​​{1}}过程DOM树中的{1}}元素,在您的情况下甚至不存在。事实上,我印象深刻的是脚本文件内容的评估没有在中途中止,因为有关DOM的假设。但这可能是因为脚本也可以与Node.js一起使用,也没有DOM。
  4. 上面的代码可以进行优化,每次需要生成SVG时都不必创建新工厂和新脚本引擎。我把它全部作为练习。
  5. canvas将整个生成的SVG文档作为文本返回。如果你想要,你必须添加一些逻辑。将所述文本保存到svg文件中。
  6. P.S。谢谢你指点我getSVGDocumentText的方向。我甚至不知道Java有一个。很高兴知道,永远不会知道。

相关问题