2009-08-25

Basic HTML to BufferedImage

This is truely a poor man's HTML renderer. It basically uses JLabel under the hood, and even has rather limited CSS support. It's all rather crude, but it might do the job for you.

public class BasicHTMLRenderer
{
   public static synchronized void render(
                      final BufferedImage img,
                      final String html,
                      final boolean makeTransparant)
   {
      if (!inited)
         init();

      Runnable task = new Runnable()
      {
         @Override
         public void run()
         {
            htmlRender.setText("<html>" + html);
            Dimension dim = new Dimension(img.getWidth(), img.getHeight());
            htmlRender.setPreferredSize(dim);
            htmlHolder.pack();

            if (makeTransparant)
            {
               Graphics2D g2d = img.createGraphics();
               g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
               g2d.fillRect(0, 0, img.getWidth(), img.getHeight());
               g2d.dispose();
            }

            Graphics g = img.getGraphics();
            htmlRender.paint(g);
            g.dispose();
         }
      };

      try
      {
         SwingUtilities.invokeAndWait(task);
      }
      catch (InterruptedException exc)
      {
         throw new IllegalStateException(exc);
      }
      catch (InvocationTargetException exc)
      {
         throw new IllegalStateException(exc);
      }
   }

   static boolean inited;
   static JFrame  htmlHolder;
   static JLabel  htmlRender;

   private static synchronized void init()
   {
      Runnable task = new Runnable()
      {
         @Override
         public void run()
         {
            htmlRender = new JLabel("<html>");
            htmlRender.setVerticalAlignment(SwingConstants.TOP);

            htmlHolder = new JFrame();
            htmlHolder.getContentPane().setLayout(new BorderLayout());
            htmlHolder.getContentPane().add(htmlRender);

            synchronized (BasicHTMLRenderer.class)
            {
               inited = true;
            }
         }
      };
      SwingUtilities.invokeLater(task);
   }

   public static synchronized void dispose()
   {
      if (!inited)
         return;

      Runnable task = new Runnable()
      {
         @Override
         public void run()
         {
            htmlRender = null;

            htmlHolder.dispose();
            htmlHolder = null;

            synchronized (BasicHTMLRenderer.class)
            {
               inited = false;
            }
         }
      };
      SwingUtilities.invokeLater(task);
   }
}

No comments:

Post a Comment