使用 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();
}
}
即使我们采用了相同的解决方案,您也必须考虑以下几点:
put
方法将其他脚本宿主对象公开给正在评估的脚本。这基本上是将脚本引擎与自定义主机一起使用的全部要点,该自定义主机不是具有特定一组 API 或 Node.js 或类似内容的 Web 浏览器。基本上,您可以使用 put
或 simulate 现有的创建您自己的 API——是的,甚至复制整个浏览器 API 集,使您的应用程序是与现代浏览器兼容的脚本主机。
- 我自己编写求值字符串,但这是一个技术问题——将本机
hash
和 size
分别作为 String
和 int
对象暴露给脚本使用 put
也可以,但是你将它们作为全局变量,这并不总是一件明智的事情,因为这些是 toSvg
过程的自然一次性参数。
- 即使您正确地包含了 JDenticon 脚本评估,您可能没有考虑到默认情况下,仅包含(和 运行ning)脚本只是调用
jdenticon
过程来查找canvas
和 svg
元素在 DOM 树中,在您的情况下甚至不存在。事实上,令我印象深刻的是,脚本文件内容的评估并没有因为对 DOM 做出假设的异常而中途中止。但这可能是因为该脚本也适用于 Node.js,它也没有 DOM。
- 上面的代码可以优化为不必在每次需要生成 SVG 时都创建新的工厂和新的脚本引擎。我把它都留作练习。
getSVGDocumentText
returns 将整个生成的 SVG 文档作为文本。如果你想,你必须添加一些逻辑,例如将所述文本保存到 *.svg
文件中。
P.S。感谢您为我指出 ScriptEngine
的方向。我什至不知道 Java 有一个。很高兴知道,永远不知道。
我正在使用此代码 (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();
}
}
即使我们采用了相同的解决方案,您也必须考虑以下几点:
put
方法将其他脚本宿主对象公开给正在评估的脚本。这基本上是将脚本引擎与自定义主机一起使用的全部要点,该自定义主机不是具有特定一组 API 或 Node.js 或类似内容的 Web 浏览器。基本上,您可以使用put
或 simulate 现有的创建您自己的 API——是的,甚至复制整个浏览器 API 集,使您的应用程序是与现代浏览器兼容的脚本主机。- 我自己编写求值字符串,但这是一个技术问题——将本机
hash
和size
分别作为String
和int
对象暴露给脚本使用put
也可以,但是你将它们作为全局变量,这并不总是一件明智的事情,因为这些是toSvg
过程的自然一次性参数。 - 即使您正确地包含了 JDenticon 脚本评估,您可能没有考虑到默认情况下,仅包含(和 运行ning)脚本只是调用
jdenticon
过程来查找canvas
和svg
元素在 DOM 树中,在您的情况下甚至不存在。事实上,令我印象深刻的是,脚本文件内容的评估并没有因为对 DOM 做出假设的异常而中途中止。但这可能是因为该脚本也适用于 Node.js,它也没有 DOM。 - 上面的代码可以优化为不必在每次需要生成 SVG 时都创建新的工厂和新的脚本引擎。我把它都留作练习。
getSVGDocumentText
returns 将整个生成的 SVG 文档作为文本。如果你想,你必须添加一些逻辑,例如将所述文本保存到*.svg
文件中。
P.S。感谢您为我指出 ScriptEngine
的方向。我什至不知道 Java 有一个。很高兴知道,永远不知道。