Skip to content

Instantly share code, notes, and snippets.

@Sixeight
Created June 22, 2009 15:17
Show Gist options
  • Save Sixeight/134016 to your computer and use it in GitHub Desktop.
Save Sixeight/134016 to your computer and use it in GitHub Desktop.
import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.net.URL;
import java.net.MalformedURLException;
import java.awt.image.BufferedImage;
import javax.imageio.*;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.*;
import javax.swing.text.html.parser.ParserDelegator;
// HTMLパーサに与えるコールバッククラス
// 画像を見つけてリストに追加する
class ImageFinder extends HTMLEditorKit.ParserCallback {
private List<Image> images;
public ImageFinder(List<Image> images)
{
this.images = images;
}
public void handleSimpleTag(HTML.Tag tag,
MutableAttributeSet attributes,
int position)
{
String className =
(String)attributes.getAttribute(HTML.Attribute.CLASS);
if (tag == HTML.Tag.IMG && "pc_img".equals(className)) {
images.add(new Image(
(String)attributes.getAttribute(HTML.Attribute.SRC)));
}
}
}
// URLクラスのラッパ
// 継承して使用する
class URLWrapper {
protected URL url;
// 与えられた文字列からURLクラスのインスタンスを生成する
// 引数がURLとして正しく無い場合はプログラムを終了する
public URLWrapper(String url)
{
try {
this.url = new URL(url);
}
catch (MalformedURLException e) {
e.printStackTrace();
System.exit(-1);
}
}
// URLからInputStreamを取得する
public InputStream getStream() throws IOException
{
return this.url.openStream();
}
}
class FlickrSearcher extends URLWrapper {
// 検索用のキーワードを渡すと適切なURLオブジェクトを生成する
public FlickrSearcher(String query)
{
super("http://www.flickr.com/search?l=cc&q=" + query);
}
}
// 取得する画像用のクラス
class Image extends URLWrapper {
// 文字列で与えられたURLから適切なURLオブジェクトを生成する
public Image(String url) { super(url); }
// 画像のファイル名を取得する
public String getName() { return this.url.getFile(); }
}
// 画像の取得を管理するクラス
class ImageDownloader {
// 取得する画像のリスト
List<Image> images;
public ImageDownloader(List<Image> images)
{
this.images = images;
}
// Downloaderを用いて同時に画像を取得する
public void getAllImages(File imageDir)
{
Iterator it = this.images.iterator();
while (it.hasNext()) {
Image img = (Image)it.next();
Downloader downloader =
new Downloader(img, imageDir);
downloader.start();
}
}
// 実際に画像の取得を行っているクラス
class Downloader extends Thread {
private Image image;
private File imageFile;
public Downloader(Image image, File imageDir)
{
this.image = image;
this.imageFile = new File(imageDir,
this.image.getName().replaceAll("^.*/", ""));
}
public void run()
{
try {
BufferedImage img = ImageIO.read(this.image.getStream());
ImageIO.write(img, "jpg", imageFile);
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class FlickrDownloader {
public static void main(String[] args)
{
// 検索に用いるキーワードの指定
// コマンドライン引数で与えない場合は"java"を使用する
String query = (args.length == 0) ? "java" : args[0];
// Flickrで検索を行うためのクラスのインスタンスを作成
FlickrSearcher fs = new FlickrSearcher(query);
// HTMLパーサのインスタンス化
ParserDelegator parser = new ParserDelegator();
// 画像を保存するディレクトリの作成
File imageDir = new File(query);
if (!imageDir.exists()) {
if (!imageDir.mkdir()) {
System.err.println("ディレクトリの作成に失敗しました");
System.exit(-1);
}
}
try {
// 取得する画像のリスト
List<Image> images = new ArrayList<Image>();
// Flickrの検索結果をパースして取得する画像のリストを作る
InputStreamReader in = new InputStreamReader(fs.getStream(), "UTF-8");
parser.parse(in, new ImageFinder(images), true);
// 画像の取得
// 0.88s users, 0.10s system, 14% CPU, 6.925 total
ImageDownloader idl = new ImageDownloader(images);
idl.getAllImages(imageDir);
// スレッドを使わない場合
// 1.07s users, 0.03s system 2% CPU, 50.472 total
// Iterator it = images.iterator();
// while (it.hasNext()) {
// Image image = (Image)it.next();
// File imageFile = new File(imageDir,
// image.getName().replaceAll("^.*/", ""));
// try {
// BufferedImage img = ImageIO.read(image.getStream());
// ImageIO.write(img, "jpg", imageFile);
// }
// catch (IOException e) {
// e.printStackTrace();
// }
// }
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment