- PR -

HTMLをGIFファイルに保存

投稿者投稿内容
PAL
ベテラン
会議室デビュー日: 2002/11/14
投稿数: 63
投稿日時: 2003-10-14 11:59
引用:

HARUさんの書き込み (2003-10-10 11:43) より:
なんとか完成させる事ができました。
Gifファイルの出来栄えを見ても、そんなに変には
なってなかったので良かったです。



参考までにどのようなコードで作成なされたのか教えて頂けませんでしょうか。
非常に面白い話題でしたので、気になっていました。
さくらば
大ベテラン
会議室デビュー日: 2002/11/12
投稿数: 145
投稿日時: 2003-10-14 15:13
こんにちは、さくらばです。

引用:

PALさんの書き込み (2003-10-14 11:59) より:
参考までにどのようなコードで作成なされたのか教えて頂けませんでしょうか。
非常に面白い話題でしたので、気になっていました。



当人じゃないのですが、以前作ったものを下に添付しておきます。
GIF じゃなくて JPEG & ちょっと長いのですが、こんな感じでは
ないでしょうか。

ローカルの HTML の場合は file:/// ... と指定してください。

ただし、JEditorPane は HTML3.2 しか使えないし、フォームや
スクリプトは全滅なので、ちょっと凝ったつくりの HTML だと
すぐ破綻します

コード:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JEditorPane;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.filechooser.FileFilter;

public class HTML2JPEG {
    private JFrame frame;
    private JEditorPane pane;
    private JTextField urlField;

    public HTML2JPEG (String url) {
        this();
        updateURL(url);
    }

    public HTML2JPEG() {
        frame = new JFrame("Print Test");
        frame.setBounds(100, 100, 600, 800);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 上部の URL を入力するパネル
        JPanel panel = new JPanel();
        urlField = new JTextField(40);
        urlField.addActionListener(new GoAction());
        panel.add(urlField);

        JButton goButton = new JButton("Go");
        goButton.addActionListener(new GoAction());
        panel.add(goButton);
        frame.getContentPane().add(panel, BorderLayout.NORTH);

        // HTML を表示するコンポーネント
        pane = new JEditorPane();
        frame.getContentPane().add(new JScrollPane(pane), BorderLayout.CENTER);


        // Save のボタン
        panel = new JPanel();
        panel.setLayout(new FlowLayout(FlowLayout.RIGHT));
        JButton printButton = new JButton("Save...");
        printButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                saveImage();
            }
        });
        panel.add(printButton);
        frame.getContentPane().add(panel, BorderLayout.SOUTH);

        frame.setVisible(true);
    }

    class GoAction implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            updateURL(urlField.getText());
        }
    }

    // イメージの出力
    private void saveImage() {
        // 出力用イメージの生成
        Dimension dim = pane.getSize();
        BufferedImage image = new BufferedImage(dim.width, dim.height, BufferedImage.TYPE_INT_RGB);

        // イメージからグラフィックコンテキストを取得
        Graphics g = image.getGraphics();

        // JEditorPane をイメージに書き込む
        // paintComponent は proteced なので使用できない
        pane.paint(g);

        // 使い終わったグラフィックコンテキストを開放
        g.dispose();

// 画像を確認したいのなら
//        JOptionPane.showMessageDialog(frame, new JLabel(new ImageIcon(image)));
        
        try {
            JFileChooser chooser = new JFileChooser(new File("."));
            // JPEG を選べるようにする
            chooser.addChoosableFileFilter(new FileFilter() {
                public boolean accept(File f) {
                    String s = f.getName();
                    int i = s.lastIndexOf('.');

                    if (i > 0 &&  i < s.length() - 1) {
                        String ext = s.substring(i+1);
                        if (ext.equalsIgnoreCase("jpg")
                            || ext.equalsIgnoreCase("jpeg")) {
                            return true;
                        }
                    }
                    return false;
                }
                    
                public String getDescription() {
                    return "JPEG File (*.jpg, *.jpeg)";
                }
            });

            // イメージの出力 Image I/O を使用
            if (JFileChooser.APPROVE_OPTION == chooser.showSaveDialog(frame)) {
                ImageIO.write(image, "JPG", chooser.getSelectedFile());
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    // URL の設定
    private void updateURL(String url) {
        try {
            // プロトコルが指定されていない場合は http:// を追加する
            if (url.indexOf("://") == -1) {
                url = "http://" + url;
            }

            pane.setPage(url);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        if (args.length > 0) {
            new HTML2JPEG(args[0]);
        } else {
            new HTML2JPEG();
        }
    }
}


HARU
会議室デビュー日: 2003/10/16
投稿数: 2
投稿日時: 2003-10-16 12:33
こんにちはHARUです。
ディスクがご臨終になり再登録しました。
仕事の方でトラブルがあり、返信が遅れて申し訳ないです。

swingの使い方自体、全然分かってないので
この件では、皆様にとても助けられました。
参考になるとは思いませんがコードを載せさせて頂きます。
コードの概要は、HTMLファイルを一度表示させて
そのイメージからGifファイルを生成しました。
内容的には、さくらばさんに載せて頂いたものとほぼ同様だと思います。
HTMLを一度表示させるのが気に入らないですが
他のやり方が分からなかったので、以下のようになってしまいました。
これだとバッチ処理的に実行するのは、厳しいですね。
とりあえず、表示させないで変換させる方法を探してみます。

コード:
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.image.BufferedImage;
import Acme.JPM.Encoders.GifEncoder;

public class Html2Gif {

  private JFrame frame;
  private JEditorPane html;
  final String line_separator = System.getProperty("line.separator");
  final String sEncode_Mode = "Shift_JIS";
    
  public Html2Gif()
  {
  }

  public boolean ConvHtmlGif(String strInHtml, String strOutGif){
    frame = new JFrame("");
    frame.setBounds(0, 0, 1200, 800);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
    // HTML表示部の構築
    html = new JEditorPane("text/html","");
    frame.getContentPane().add(new JScrollPane(html), BorderLayout.CENTER);
    File fiHtml = new File(strInHtml);
    html.setText(getTextFromFile(fiHtml));
    frame.setVisible(true);
        
    // 出力用イメージの生成
    Dimension dimOut = html.getSize();
    BufferedImage bimg = new BufferedImage(dimOut.width, 
                                           dimOut.height,
                                           BufferedImage.TYPE_INT_RGB);
    Graphics g = bimg.getGraphics();
    html.paint(g);
    g.dispose();

    // GifファイルのFileオブジェクト生成
    File fiGif = new File(strOutGif);
    try{
      fiGif.createNewFile( );
    } catch(IOException ioe){          
    }

    boolean bFlag = this.makeGifFile(fiGif, bimg);
    if (bFlag == true){
      return true;
    } else{
      return false;
    }
  }

  // HTMLをGIFエンコーディングする。
  private boolean makeGifFile(File file, Image image){

    FileOutputStream stream = null;
    try{
      stream = new FileOutputStream(file);
      GifEncoder encoder = new GifEncoder(image, stream);
      encoder.encode();
      stream.close();
      return true;    
    } catch(IOException e){
      try{ stream.close(); }catch(IOException ie){}
      return false;
    } catch(Exception ex){
      try{ stream.close(); }catch(IOException ie){}
      return false;
    }
  }

  // メソッド名 : HTMLファイル解析処理<BR>
  public String getTextFromFile(File file){
    String text = "";
    try{
      // 指定のエンコーディングで入力ストリームを構築
      FileInputStream input = new FileInputStream(file);
      BufferedReader reader = new BufferedReader(new InputStreamReader
                                                     (input,sEncode_Mode));
      // Stringオブジェクトに読み込む
      String buffer;
      while((buffer = reader.readLine()) != null){
        // Metaタグを含む行を無視
        if(buffer.toLowerCase().indexOf("meta http-equiv") == -1) {
          text = text + buffer + line_separator;
        }
      }
    } catch(IOException e){
      System.err.println(e);
    }  
    return(text);
  }
}


かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-10-16 14:08
引用:

HTMLを一度表示させるのが気に入らないですが
他のやり方が分からなかったので、以下のようになってしまいました。
これだとバッチ処理的に実行するのは、厳しいですね。
とりあえず、表示させないで変換させる方法を探してみます。


コンポーネントをリアライズ(表示可能状態)にしてやればできそうな気がします。
リアライズの方法はComponent#setvisible(), show(), pack()を呼ぶ事です。
このうち、setVisible()とshow()は画面に表示されてしまうため、残された手段はpack()を使用することになると思います。ただしpack()を呼ぶと直接指定した領域のサイズは無視されます。小手先な回避方法は、JEditorPaneを継承し、getPreferredSize()で希望のサイズが返されるようオーバーライドする事です。

ところで、リアライズすることなく変換することはできなかったのですか?
PAL
ベテラン
会議室デビュー日: 2002/11/14
投稿数: 63
投稿日時: 2003-10-16 15:09
HARUさん、さくらばさんありがとうございました。ためになります。
さくらば
大ベテラン
会議室デビュー日: 2002/11/12
投稿数: 145
投稿日時: 2003-10-16 16:04
こんにちは、さくらばです。

引用:

かずくんさんの書き込み (2003-10-16 14:08) より:

コンポーネントをリアライズ(表示可能状態)にしてやればできそうな気がします。



できません。

JEditorPane が HTML を表示するときに使用する HTMLEditorKit は、
表示を行わない限りレンダリングを開始しません。

したがって、pack してもだめです。

# HTMLEditorKit を派生させたクラスを自作すればできるかもしれませんが...

同じ JEditorPane でもプレインテキストを表示する場合には、DefaultEditorKit
が使用されるため、表示しなくてもレンダリングが行えます。

引用:

小手先な回避方法は、JEditorPaneを継承し、getPreferredSize()で希望の
サイズが返されるようオーバーライドする事です。



JComponent#setPreferredSize を使用する方がスマートです。
無駄な継承をさけることができます。
HARU
会議室デビュー日: 2003/10/16
投稿数: 2
投稿日時: 2003-10-16 16:08
引用:

ところで、リアライズすることなく変換することはできなかったのですか?



申し訳ないですが
試してないので、なんとも言えないです。
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-10-16 18:33
引用:

JComponent#setPreferredSize を使用する方がスマートです。
無駄な継承をさけることができます。


普段、AWTばかりなので、このメソッドには気づきませんでした。
フォローありがとうございます。

スキルアップ/キャリアアップ(JOB@IT)