B4J Question B4J program (Non-UI) HTML to image

hzq200409

Member
Licensed User
This is a piece of java source code I searched, it runs without error. But somehow it doesn't render HTML content as an image. Can anyone who knows java language help me find out why? Related Documents.
 

Attachments

  • html2ImageTest.zip
    26.4 KB · Views: 57
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
You need to add a frame so the label can be rendered before getting the image of it

B4X:
#IF JAVA
import java.awt.*;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;



public static void htmlToImage(String html, String contentType,int width, int height) throws Exception {
	JFrame frame = new JFrame("panel");
	JLabel label = new JLabel(html);
    label.getPreferredSize().width = width;
    label.getPreferredSize().height = height;
	label.setOpaque(true); 
	label.setBackground(Color.WHITE);
    System.out.println(label.getText());
	frame.setSize(width,height);
	frame.add(label);
	
	frame.show();
	
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    
	//Use Graphics2D to render the JLabel to the image
    Graphics2D g2d = image.createGraphics();
	g2d.setPaint(Color.WHITE);
	g2d.fillRect(0, 0, width, height);
    label.paint(g2d);
    g2d.dispose();


    ImageIO.write(image, "JPG", new File("image.jpg"));
}
#End If

(Note: It wont display like a web page, just the html as text on an image.)
 
Last edited:
Upvote 0

hzq200409

Member
Licensed User
You need to add a frame so the label can be rendered before getting the image of it

B4X:
#IF JAVA
import java.awt.*;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;



public static void htmlToImage(String html, String contentType,int width, int height) throws Exception {
    JFrame frame = new JFrame("panel");
    JLabel label = new JLabel(html);
    label.getPreferredSize().width = width;
    label.getPreferredSize().height = height;
    label.setOpaque(true);
    label.setBackground(Color.WHITE);
    System.out.println(label.getText());
    frame.setSize(width,height);
    frame.add(label);
   
    frame.show();
   
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
   
    //Use Graphics2D to render the JLabel to the image
    Graphics2D g2d = image.createGraphics();
    g2d.setPaint(Color.WHITE);
    g2d.fillRect(0, 0, width, height);
    label.paint(g2d);
    g2d.dispose();


    ImageIO.write(image, "JPG", new File("image.jpg"));
}
#End If
Thank you very much! Now we have the image. But instead of parsing the HTML, the source code is displayed. Is the library unable to parse it?
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
It wont parse the html, it's a label not a web browser.

Write a tiny ui app to load the html into a webview then snapshot that and save to disk.
 
Upvote 0

hzq200409

Member
Licensed User
It wont parse the html, it's a label not a web browser.

Write a tiny ui app to load the html into a webview then snapshot that and save to disk.
I know that the UI-based webview can save snapshots as jpeg files. I've already tried. Is it possible to implement Non-UI programs?
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
What I meant in post #5 was

Write a tiny ui app to snapshot the webview that takes the html as an argument
Pass the html to it from the non-ui app (jshell etc)
grab the snapshot in the ui app and save to disk.
 
Upvote 0

hzq200409

Member
Licensed User
What I meant in post #5 was

Write a tiny ui app to snapshot the webview that takes the html as an argument
Pass the html to it from the non-ui app (jshell etc)
grab the snapshot in the ui app and save to disk.
Thanks again for your attention! I actually needed to upload the html snapshot to a third party (a lot more steps and overhead if done as above). If only there were a better solution.) . Sorry, I don't know if this will work without the system being logged in to the desktop.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
There is a JFXPanel in swing that may allow you to insert a (javafx) webview in a non-ui app, but I haven't tried.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
jEditorPane displays html in the swing environment. I tried this code in a non-ui app and it does display. Whether you can leverage it to do what you want from there I don't know. Documentation is here. Also I don't know how good/old the HTML implementation is.

B4X:
'Non-UI application (console / server application)
#Region Project Attributes
    #CommandLineArgs:
    #MergeLibraries: True
#End Region

Sub Process_Globals
   
End Sub

Sub AppStart (Args() As String)
   
    Dim MeJO As JavaObject = Me
    MeJO.RunMethod("showHtml",Array(HTML))
   
   
End Sub

private Sub HTML As String
    Return $"<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>title</title>
  </head>
  <body>
    <!-- page content -->
    <span style='color:Red'>Test html text</span>
  </body>
</html>"$
End Sub


#if java
import javax.swing.JEditorPane;
import javax.swing.JScrollPane;
import javax.swing.JFrame;
import java.io.IOException;
import java.awt.Dimension;

public static void showHtml(String html){


    JEditorPane jep = new JEditorPane();
    jep.setEditable(false);  

/*    try {
      jep.setPage("http://www.yoursite.com");
    }catch (IOException e) { */
   
      jep.setContentType("text/html");
      jep.setText(html);
   
    /*} */

    JScrollPane scrollPane = new JScrollPane(jep);    
    JFrame f = new JFrame("Test HTML");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.getContentPane().add(scrollPane);
    f.setSize(800,600);
    f.setVisible(true);

}
#End If
 
Upvote 0

hzq200409

Member
Licensed User
jEditorPane displays html in the swing environment. I tried this code in a non-ui app and it does display. Whether you can leverage it to do what you want from there I don't know. Documentation is here. Also I don't know how good/old the HTML implementation is.

B4X:
'Non-UI application (console / server application)
#Region Project Attributes
    #CommandLineArgs:
    #MergeLibraries: True
#End Region

Sub Process_Globals
  
End Sub

Sub AppStart (Args() As String)
  
    Dim MeJO As JavaObject = Me
    MeJO.RunMethod("showHtml",Array(HTML))
  
  
End Sub

private Sub HTML As String
    Return $"<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>title</title>
  </head>
  <body>
    <!-- page content -->
    <span style='color:Red'>Test html text</span>
  </body>
</html>"$
End Sub


#if java
import javax.swing.JEditorPane;
import javax.swing.JScrollPane;
import javax.swing.JFrame;
import java.io.IOException;
import java.awt.Dimension;

public static void showHtml(String html){


    JEditorPane jep = new JEditorPane();
    jep.setEditable(false); 

/*    try {
      jep.setPage("http://www.yoursite.com");
    }catch (IOException e) { */
  
      jep.setContentType("text/html");
      jep.setText(html);
  
    /*} */

    JScrollPane scrollPane = new JScrollPane(jep);   
    JFrame f = new JFrame("Test HTML");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.getContentPane().add(scrollPane);
    f.setSize(800,600);
    f.setVisible(true);

}
#End If
I tried without success.
 
Upvote 0

hzq200409

Member
Licensed User
What did you try? The code as is? Provide your code (if different) or any error messages if you want help with this.
B4X:
'Non-UI application (console / server application)
#Region Project Attributes
'    #AdditionalJar: htmlunit-3.6.0-OSGi.jar
    #CommandLineArgs:
    #MergeLibraries: True
#End Region

Sub Process_Globals
    
End Sub

Sub AppStart (Args() As String)
    Dim jo As JavaObject = Me
    Dim html As String = File.ReadString(File.DirApp,"Html.txt")
    jo.RunMethod("htmlToImage",Array(html,"html.jpg",1000,1360))
End Sub




#if java
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.text.*;
import javax.swing.text.html.*;
import javax.swing.text.html.parser.*;

import javax.swing.JEditorPane;

public static void htmlToImage(String html, String filename, int width, int height) throws Exception {
    //System.out.println(html);
    /*
    HTMLDocument doc = new HTMLDocument();
    ParserDelegator pd = new ParserDelegator();
    pd.parse(new StringReader(html), doc.getReader(0), true);
    */
    
    JEditorPane jep = new JEditorPane("text/html",html);

    System.out.println(jep.getText()); //-->This is not the content of the parameter (attachment).
}

#End If
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
I'm not going to be able to look at it now until this evening. If no one else has replied, I will take a look.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
This displays the file and logs the correct content.

I added a file to the assets directory and read it from there rather that DirApp, and added the rest of the code to display it.
 

Attachments

  • nonuihtml.zip
    1.5 KB · Views: 43
Upvote 0

hzq200409

Member
Licensed User
This displays the file and logs the correct content.

I added a file to the assets directory and read it from there rather that DirApp, and added the rest of the code to display it.
It's not ideal. HTML like attachments cannot be displayed.
 

Attachments

  • Html.txt
    112.1 KB · Views: 48
Last edited:
Upvote 0
Top