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

Save an SVG image from a website using Java (desktop)

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

<!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)

它的代码是什么?

Edit #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)方法。因此,如果有人知道如何解决这个问题,那就太好了。

你更新的问题包括 运行 显然内置于 Java SE 中的 Java 脚本解释器中的原始代码的有趣想法,让我进一步追求这种方法,导致我测试生成 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 浏览器。基本上,您可以使用 putsimulate 现有的创建您自己的 API——是的,甚至复制整个浏览器 API 集,使您的应用程序是与现代浏览器兼容的脚本主机。
  2. 我自己编写求值字符串,但这是一个技术问题——将本机 hashsize 分别作为 Stringint 对象暴露给脚本使用 put 也可以,但是你将它们作为全局变量,这并不总是一件明智的事情,因为这些是 toSvg 过程的自然一次性参数。
  3. 即使您正确地包含了 JDenticon 脚本评估,您可能没有考虑到默认情况下,仅包含(和 运行ning)脚本只是调用 jdenticon 过程来查找canvassvg 元素在 DOM 树中,在您的情况下甚至不存在。事实上,令我印象深刻的是,脚本文件内容的评估并没有因为对 DOM 做出假设的异常而中途中止。但这可能是因为该脚本也适用于 Node.js,它也没有 DOM。
  4. 上面的代码可以优化为不必在每次需要生成 SVG 时都创建新的工厂和新的脚本引擎。我把它都留作练习。
  5. getSVGDocumentText returns 将整个生成的 SVG 文档作为文本。如果你想,你必须添加一些逻辑,例如将所述文本保存到 *.svg 文件中。

P.S。感谢您为我指出 ScriptEngine 的方向。我什至不知道 Java 有一个。很高兴知道,永远不知道。