如何使用html在swing组件上渲染内部图像? [英] How to render a internal image on a swing component using html?

查看:437
本文介绍了如何使用html在swing组件上渲染内部图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

  public static void main(String [] args){
JFrame frm = new JFrame();
的JEditorPane窗格=新的JEditorPane( text / html的, < HTML><主体>试验<峰; br>< IMG SRC = \ 数据:图像/ PNG; BASE64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACuklEQVR42sWVv09TURTH71AXE40xaRdXEwbD4ODiIFr6EwcXN1cnR0cXoyTWUjcH3n0dDG4aEwcaoqggWn8ERWtoKdVBoA2lxbj4BxzPt + eaPEn7nhDeleRDTr733vP9vtvXU0VE6n8i // 79L5KdUKVUXtHobUXxnIAaGtawZzcNdxvgEIw2u0Va39SMa9A9DWvYE2aAKJ4WhpPTipySgBoa1rAnzAAxXPnalkvOjCL3iYAaGtawJ / QA650iaTYuPhVQQ7MbAOazAmqrAdb4hXOe8fW / EFBDsxdgmwM8Z / M5ATU0ewF + cACYvxRQQ7MS4NwtRd9xA / NsviCghoa1vQaIjP2ZcLnBxNng9E1F37p3yYH5awE1NKxhj18PeIx5J6YJ0Jtwaz / vUKObZwoDqW8VaL5xkfQr / gaUBdTQsOZ3Fr3h8dfENAGiCU5X79ygSW7oBKDf8JO / ZXMDamhB59AbHomcZ2KaADGIy + 1r5HAjjabv + lMMYNA59ERveCS8L6s3QKV9lRxsfs + H9hn0RG94DAyw1L5CepEPfOCn8cFd7I / vGQa94dE3QJpfjMr2ZZr6oui + d / C + + c8OP0tALNKz5nUVveKTzfQKcL6hfmQnVWxxEin9uR8YVlVuXSC xsQE1NKxhj18PeCSuq / LOL / AIc5KJM6M + ZHB9C60LpD + xuQE1NHO1mYAeI8yJnV / DAyZELIChJJvMtVKkK2xuQA0tKQGGAnpEjXlkT6M4xSazzTPk8ufpBVrKxm8BTGaap8itsvGyoSqatQCljWFya2LcoyaatQCPW8dJr / BnXzOsiGY twKPmMdKrbFw3rIpmJUCaTR60jlLxK199Q0ANLW0jQJaHycPOQZpq8mTbMDRFy + bDDxDNjKsqjPC0XqAlvRMupACHmWHmbOCECylAxISIBk64kALs + 99vkl5XSNCDZhMAAAAASUVORK5CYII = \ >< /体>< / HTML> 中);
pane.setEditable(false);
frm.getRootPane()。setContentPane(pane);
frm.pack();
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.setVisible(true);
}

我正在尝试使用base64在JEditorPane上渲染图像编码来存储图像。它不需要是base64,但就我在尝试在JEditorPane中呈现HTML内容时得到的那样,但我需要使用BufferedImage上的图像(它由应用程序生成),并且会真的不希望将图像保存到硬盘上的文件中。



我可以以某种方式在Swing组件中显示BufferedImage以及HTML(显示它在由IMG标签给出的地方 - html代码也是由应用程序生成的)?

解决方案

我必须重写一个的Java类并扩展了另一个类,但是在JEditorPane上获得了HTML下的BASE64图像。我会发布我的解决方案,以防将来有人需要它......

首先,创建一个特殊的HTMLEditorKit,它将使用重写的ImageView类作为HTML.Tag .IMG

  class BASE64HTMLEditorKit extends HTMLEditorKit {

private static HTMLFactory factory = null;

@Override
public ViewFactory getViewFactory(){
if(factory == null){
factory = new HTMLFactory(){

@Override
public View create(Element elem){
AttributeSet attrs = elem.getAttributes();
Object elementName = attrs.getAttribute(AbstractDocument.ElementNameAttribute);
Object o =(elementName!= null)? null:attrs.getAttribute(StyleConstants.NameAttribute);
if(o instanceof HTML.Tag){
HTML.Tag kind =(HTML.Tag)o;
if(kind == HTML.Tag.IMG){
// HERE是对特殊类的调用...
返回新的BASE64ImageView(elem);
}
}
return super.create(elem);
}
};
}
返回工厂;
}

}

完成后,类,基于openjdk代码。
下载源代码此处,并打开文件openjdk / jdk / src /分享/班/使用javax /秋千/文本/ HTML / ImageView.java。因为几乎所有东西都是私有的,所以我发现它更容易完全复制,然后更改加载BASE64映像所需的方法:

  private void loadImage(){
String b64 = getBASE64Image();
BufferedImage newImage = null;
try(ByteArrayInputStream bais = new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(b64))){
newImage = ImageIO.read(bais);
} catch(IOException ex){
...
}
image = newImage;
}

private String getBASE64Image(){
String src =(String)getElement()。getAttributes()。getAttribute(HTML.Attribute.SRC);
if(src == null){
return null;

return src.replaceFirst(data:image / png; base64,,);
}

getBASE64Image方法只是削减属性的非BASE64部分。
loadImage方法是必须改变的方法,如果它公开的话,会帮助从解决方案中删除大量代码...

如果有人有一个更好,最好更小(我的代码有1000行),请分享...


I have the following code:

public static void main(String[] args) {
    JFrame frm = new JFrame();
    JEditorPane pane = new JEditorPane("text/html", "<html><body>test<br><img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACuklEQVR42sWVv09TURTH71AXE40xaRdXEwbD4ODiIFr6EwcXN1cnR0cXoyTWUjcH3n0dDG4aEwcaoqggWn8ERWtoKdVBoA2lxbj4BxzPt+eaPEn7nhDeleRDTr733vP9vtvXU0VE6n8i//79L5KdUKVUXtHobUXxnIAaGtawZzcNdxvgEIw2u0Va39SMa9A9DWvYE2aAKJ4WhpPTipySgBoa1rAnzAAxXPnalkvOjCL3iYAaGtawJ/QA650iaTYuPhVQQ7MbAOazAmqrAdb4hXOe8fW/EFBDsxdgmwM8Z/M5ATU0ewF+cACYvxRQQ7MS4NwtRd9xA/NsviCghoa1vQaIjP2ZcLnBxNng9E1F37p3yYH5awE1NKxhj18PeIx5J6YJ0Jtwaz/vUKObZwoDqW8VaL5xkfQr/gaUBdTQsOZ3Fr3h8dfENAGiCU5X79ygSW7oBKDf8JO/ZXMDamhB59AbHomcZ2KaADGIy+1r5HAjjabv+lMMYNA59ERveCS8L6s3QKV9lRxsfs+H9hn0RG94DAyw1L5CepEPfOCn8cFd7I/vGQa94dE3QJpfjMr2ZZr6oui+D/c+c8OP0tALNKz5nUVveKTzfQKcL6hfmQnVWxxEin9uR8YVlVuXSC+xsQE1NKxhj18PeCSuq/LOl/AIc5KJM6M+ZHB9C60LpD+xuQE1NHO1mYAeI8yJnV/DAyZELIChJJvMtVKkK2xuQA0tKQGGAnpEjXlkT6M4xSazzTPk8ufpBVrKxm8BTGaap8itsvGyoSqatQCljWFya2LcoyaatQCPW8dJr/BnXzOsiGYtwKPmMdKrbFw3rIpmJUCaTR60jlLxK199Q0ANLW0jQJaHycPOQZpq8mTbMDRFy+bDDxDNjKsqjPC0XqAlvRMupACHmWHmbOCECylAxISIBk64kALs+99vkl5XSNCDZhMAAAAASUVORK5CYII=\"></body></html>");
    pane.setEditable(false);
    frm.getRootPane().setContentPane(pane);
    frm.pack();
    frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frm.setVisible(true);
}

What I'm trying to do is render a image on the JEditorPane using base64 codification to store the image. It does not need to be base64, but that's as far as I got while trying to render HTML content on the JEditorPane, but I need to use an image that is on a BufferedImage(It is generated by the application.), and, would really prefer not to have to save the image to a file in the hard disk.

Can I, somehow, display an BufferedImage in a swing component along with HTML(displaying it in the place given by the IMG tag - the html code is generated by the application too)?

解决方案

I had to rewrite one of the Java classes and extend another, but got the BASE64 image working under HTML on the JEditorPane. I'll post my solution in case someone needs it in the future...

First, create a Special HTMLEditorKit that will use the rewritten ImageView class for the HTML.Tag.IMG

class BASE64HTMLEditorKit extends HTMLEditorKit {

    private static HTMLFactory factory = null;

    @Override
    public ViewFactory getViewFactory() {
        if (factory == null) {
            factory = new HTMLFactory() {

                @Override
                public View create(Element elem) {
                    AttributeSet attrs = elem.getAttributes();
                    Object elementName = attrs.getAttribute(AbstractDocument.ElementNameAttribute);
                    Object o = (elementName != null) ? null : attrs.getAttribute(StyleConstants.NameAttribute);
                    if (o instanceof HTML.Tag) {
                        HTML.Tag kind = (HTML.Tag) o;
                        if (kind == HTML.Tag.IMG) {
                            // HERE is the call to the special class...
                            return new BASE64ImageView(elem);
                        }
                    }
                    return super.create(elem);
                }
            };
        }
        return factory;
    }

}

With that done, implement the special class, based on the openjdk code. Download the source code here, and open the file openjdk/jdk/src/share/classes/javax/swing/text/html/ImageView.java. Because it have almost everything private, I found it easier to copy it entirely and then change the method needed to load BASE64 Images:

private void loadImage() {
    String b64 = getBASE64Image();
    BufferedImage newImage = null;
    try (ByteArrayInputStream bais = new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(b64))) {
        newImage = ImageIO.read(bais);
    } catch (IOException ex) {
        ...
    }
    image = newImage;
}

private String getBASE64Image() {
    String src = (String) getElement().getAttributes().getAttribute(HTML.Attribute.SRC);
    if (src == null) {
        return null;
    }
    return src.replaceFirst("data:image/png;base64,", "");
}

The getBASE64Image method just cuts the non BASE64 part of the attribute. The loadImage method is the one that has to be changed, and if it where public, would have helped cut a lot of code from the solution...

If someone has a better and preferably smaller (mine have 1000 lines of code), please share it...

这篇关于如何使用html在swing组件上渲染内部图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆