JavaFX2 WebView 和内存中图像

标签 java image webview javafx

问题是:我有几个图像,并且想在 JavaFX 的 WebView 中显示 HTML 时使用它们。 .

当前的实现非常明显:有一个文件,链接到 HTML 内容。我假设WebView不会从 JEditorPane 回归即使图像在整个内容中被引用 10 000 次,也只会执行一次 I/O 操作。

但是,如果有一个 Image 就太好了实例并在遇到相关 <img> 时将其提供给 WebView标签。

我发现有一个很好的半解决方案涉及 URL处理,但问题仍然存在:你有一个 Image转换为存储格式(BMP、带有专有扩展的 PNG 等)并将其保留在内存中的实例。然而,这意味着每次 WebView 需要图像分辨率时,它必须手动从二进制数据中解析图像。最后,您只有一个映射到内存的文件以及一个内部 Image实例而不是共享 Image实例。

JEditorPane ,您可以按Image s到它的图像缓存并摆脱此类问题。不幸的是,从 Java 7 开始,该组件就无法使用并且不存在问题。

基本上,有没有机会WebView/WebEngine维护这样的缓存/等效项,有没有办法预先填充它?

最佳答案

    /**
     * Encodes the image as a whole into PNG, then into Base64 and finally into an URI suitable for the HTML {@code <img>} tag.
     * 
     * @param image an image
     * @return image as URI (image within the URI)
     * @throws IIOException if there is a fault with an image writer
     * @throws IOException in case of a general I/O error
     */
    public static final String getImageSrcForWebEngine(RenderedImage image) throws IIOException, IOException
    {
        final ByteArrayOutputStream output = new ByteArrayOutputStream();
        ImageIO.write(image, "PNG", output);
        return "data:base64," + Base64.getMimeEncoder().encodeToString(output.toByteArray());
    }

使用示例:

RenderedImage image = […];
String tag = "<img src=\"" + getImageSrcForWebEngine(image) + "\" border=\"0\" />";

SSCCE:

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;

import javax.imageio.IIOException;
import javax.imageio.ImageIO;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class WebViewWithMemoryImages extends Application
{
    private static String IMAGE_IN_MEMORY;

    @Override
    public void start(Stage primaryStage)
    {
        WebView webView = new WebView();
        webView.getEngine().loadContent("<html><body><img src=\"" + IMAGE_IN_MEMORY + "\"></body></html>");
        primaryStage.setScene(new Scene(webView, 420, 420));
        primaryStage.show();
    }

    public static void main(String[] args) throws Exception
    {
        BufferedImage image = new BufferedImage(400, 400, BufferedImage.TYPE_INT_BGR);
        Graphics2D g = image.createGraphics();
        try
        {
            g.setColor(Color.RED);
            g.fillRect(0, 0, 400, 400);
            g.setColor(Color.WHITE);
            g.fillRect(50, 50, 300, 300);
            g.setColor(Color.BLACK);
            g.fillRect(100, 100, 200, 200);
            g.drawString("No image files were used in this WebView.", 90, 70);
        }
        finally
        {
            g.dispose();
        }
        IMAGE_IN_MEMORY = getImageSrcForWebEngine(image);

        launch(args);
    }

    public static String getImageSrcForWebEngine(RenderedImage image) throws IIOException, IOException
    {
        final ByteArrayOutputStream output = new ByteArrayOutputStream();
        ImageIO.write(image, "PNG", output);
        return "data:base64," + Base64.getMimeEncoder().encodeToString(output.toByteArray());
    }
}

关于JavaFX2 WebView 和内存中图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22984430/

相关文章:

java - 如何将文本发送到在 selenium webdriver 中使用自动完成功能的搜索框

php - 在 PHP 或 Unix 命令行中确定图像分辨率和文件类型的最快方法?

java - 如何设置 Android WebView 使其与 Android 浏览器相同?

javascript - 在 Chrome App Webview 中加载本地文件

c# - Monodroid WebView 加载 SSL 页面

java - 在 Java 中将随机字符放置在数组板上

java - 无法通过 Dockerized WebLogic 将 Debug 设置为适用于 Java,不能使用 IntelliJ 或 Studio Code

java - 如何使用 GridLayout 或 GridBagLayout 垂直填充 JPanel?

php - 如何在 WordPress 中显示来自 get_children 数组的特定图像

css - 单独 div 中两行图像之间的空间,仅出现在一个特定行上