I want to show a picture in javafx webview local html. here is my code, But I found the picture can not be shown.The image url is "file:/D:/a.jpg".
//Main WebViewBrowser.java
public class WebViewBrowser extends Application {
@Override public void start(Stage stage) throws Exception {
WebView browser = new WebView();
browser.setContextMenuEnabled(false);
WebEngine webEngine = browser.getEngine();
String url = this.getClass().getResource("t.html").toExternalForm();
System.out.println(url);
//out put is "jar:file:/D:/data/netbeans/WebViewBrowser1/dist/run690102893/WebViewBrowser.jar!/webviewbrowser/t.html"
Scene scene = new Scene(browser);
webEngine.load(url);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
//t.html
//.............
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div>TODO write content</div>
<img src="a.jpg" alt="aaa"/> <!-- the relative path works -->
<img src="file:/D:/a.jpg" alt="aaa"/> <!-- the absolute path dos not work.why ?-->
</body>
</html>
I just want to know how i can load the image which url is like 'file:/D:/a.jpg'. Thak you very much.
With the new description of your problem, I can reproduce it too: it seems WebView
can't access to local files if the web page is loaded from a jar file.
After searching for a while, I've just found this bug report on JIRA (you need to be registered to access to it):
As it is pointed out in the report, if you right-click over the alt description, you can load the image on a new window, what means it's not a problem of security restrictions (sandbox).
For the moment there's no easy solution. One that is proposed also here is encoding the image as a base64 string:
<img src="data:image/png;base64,(...)" />
public String pathToBase64(String path) throws IOException {
return Base64.getEncoder().encodeToString(Files.readAllBytes(Paths.get(path)));
}
Other solution is using webEngine.loadContent()
. There's already an example here that may work.
EDIT
As the OP points out, there's another workaround to deal with local images loading, based on the use of a custom URL protocol. In this question there's already a working solution. For the image loading this is a possible implementation:
private void loadImage() throws IOException {
String imgPath = getURL().toExternalForm();
String ext = imgPath.substring(imgPath.lastIndexOf('.')+1);
imgPath = imgPath.startsWith(PROTOCOL+"://") ?
imgPath.substring((PROTOCOL+"://").length()) :
imgPath.substring((PROTOCOL+":").length());
try{
BufferedImage read = ImageIO.read(new File(imgPath));
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(read, ext, os);
data=os.toByteArray();
} catch(IOException ioe){
System.out.println("IO exception: "+ioe);
}
}