【问题标题】:Save an SVG image from a website using Java (desktop)使用 Java(桌面)从网站保存 SVG 图像
【发布时间】:2016-11-06 05:39:14
【问题描述】:

我正在使用此代码 (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)

它的代码是什么?

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

【问题讨论】:

  • 你看过JDenticon的文档吗?
  • @amn 好吧,我想我有但还没有找到 Java 的解决方案。
  • Java? JDenticon 是一个 JavaScript 库——它在客户端工作。也就是说,我认为您能够通过 Node.js 在服务器端呈现图标。您可能不得不将 JDenticon 移植到 Java 源代码中,以便让它将图标呈现为 Java 应用程序。另外,请记住,您不必为图标使用 SVG - 您可以使用 canvas,这也记录在 JDenticon 页面上。
  • @amn 生成画布会更容易吗?我不管是canvas还是svg,我只是想最后通过Java获取图片。
  • 您需要向我解释 Java 在您的 JDenticon 应用程序中的哪些方面。否则很难说。在我看来,对于您的应用程序,canvassvg 并不重要。 Java 可以是一个小程序(可以说已被弃用),也可以是一个 servlet(服务器端)或独立的桌面程序。 Java 有很多东西。您能否更新您的问题并详细说明 Java 的位置和方式?

标签: javascript java svg javax.script identicon


【解决方案1】:

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

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

【讨论】:

  • 这解决了问题,非常感谢。我也在尝试用java编写代码,看看它是否在速度上有很大的不同。
  • 它无疑会 - 建立和使用脚本主机来运行相当少量的我认为是解释(而不是编译)代码的开销永远不可能将不仅仅是简单的运行 Java 代码。我还建议您使其通用——不必依赖于图形上下文——只需使用一个接受矢量图形调用的接口,这样人们就可以在它之上实现自己的类。把它放在 Github 上,可能与JDenticon repo 本身合并。还有……利润! ;-)
猜你喜欢
  • 2014-06-08
  • 1970-01-01
  • 1970-01-01
  • 2017-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
相关资源
最近更新 更多