|
|
連載 .NETでWindowsアプリを作ろう
第1回 Google画像検索アプリを作ろう
デジタルアドバンテージ 遠藤 孝信
2005/06/25 |
 |
|
Google用プラグインの作成
Googleの下調べが終わり、必要なモジュールもそろったところで、実際にGoogle用プラグインをコーディングしていきましょう。
ここではVS.NETをいったん閉じるか、あるいはもう1つVS.NETを起動して、まずGoogle用プラグインの新しいプロジェクト「WISGoogle」を作ります。プラグインとなるDLLファイルを作成するので、新しいプロジェクトではテンプレートとして「クラス ライブラリ」を選択します。
プラグインは、先ほど作成したWebImageクラスとIWebImageインターフェイスに基づいてコーディングを行うため、プロジェクトの準備が出来たら、先ほど作成したDLLファイルをWISGoogleプロジェクトの参照設定に追加します。これはソリューション・エクスプローラでWISGoogleプロジェクト内にある[参照設定]を右クリックし、[参照の追加]で先ほど作成したWebImageLib.dllを指定します。
さらにURLエンコーディング用のHttpUtilityクラス(System.Web名前空間)が含まれている.NETのコンポーネントである「System.Web.dll」も参照設定が必要となります(クラス・ライブラリ作成用のテンプレートでは、デフォルトではこのコンポーネントは参照設定されていません)。
では、コードを書いていきましょう。クラス名はGoogleImageクラスとします。このクラスは自動作成されているファイル「Class1.cs」を「GoogleImage.cs」にリネームして記述します。
GoogleImageクラスでは次の2つのフィールドによりオブジェクトの内部状態を管理します(VB.NET版では_hasNextと_currentPage)。
- hasNext:次のページが存在するかどうかを示すbool値
- currentPage:現在の検索結果ページのページ番号
hasNextフィールドは1ページを取得したときに「次へ」のリンクがあればtrueに、なければfalseにセットされます。currentPgaeフィールドは、GetImagesメソッドにより取得対象となるページを示すものです。
Web検索を行い、その結果をWebImageオブジェクトの配列として返すGetImagesメソッドの内部は大まかには次のようになります(全リストは冒頭で紹介したダウンロード用のプロジェクトか、リスト脚注にあるGoogleImage.csあるいはGoogleImage.vbを参照してください)。
static Encoding sjisEnc = Encoding.GetEncoding("Shift_JIS");
string url = "http://images.google.co.jp/images?hl=ja&q={0}&start={1}&filter=0&safe=off";
public WebImage[] GetImages(string query)
{
ArrayList images = new ArrayList();
if (query != "")
{
string html = readPage(
String.Format(url, System.Web.HttpUtility.UrlEncode(query, sjisEnc), currentPage * 20));
……略……
文字列htmlを解析して必要なURLを切り出し、
すべてArrayListコレクションに追加していく
images.Add(new WebImage(small, large, page));
……略……
// 「次へ」のリンク・テキストをチェック
hasNext = html.IndexOf("<span class=b><b>次へ</b></span>") == -1 ? false : true;
}
// 配列に変換
return (WebImage[])images.ToArray(typeof(WebImage));
}
|
Shared sjisEnc As Encoding = Encoding.GetEncoding("Shift_JIS")
Dim url As String = "http://images.google.co.jp/images?hl=ja&q={0}&start={1}&filter=0&safe=off"
Public Function GetImages(ByVal query As String) As WebImageLibVB.WebImage() Implements WebImageLibVB.IWebImage.GetImages
Dim images As New ArrayList
If query <> "" Then
Dim html As String = readPage( _
String.Format(url, System.Web.HttpUtility.UrlEncode(query, sjisEnc), _currentPage * 20))
……略……
文字列htmlを解析して必要なURLを切り出し、
すべてArrayListコレクションに追加していく
images.Add(New WebImage(small, large, page))
……略……
' 「次へ」のリンク・テキストをチェック
If html.IndexOf("<span class=b><b>次へ</b></span>") = -1 Then
_hasNext = False
Else
_hasNext = True
End If
End If
' 配列に変換
Return CType(images.ToArray(GetType(WebImage)), WebImage())
End Function
|
|
IWebImageインターフェイスのGetImagesメソッドの実装の概略(上:C#、下:VB.NET) |
|
|
readPageメソッドは、指定されたWebページを読み取ってHTMLデータを文字列として返します(これについては「.NET TIPS:WebClientクラスでWebページを取得するには?」を参照)。
ここでは、readPageメソッドにより読み込んだ検索結果ページを解析し、必要なURLを切り出して、順にコレクションに追加していきます。そしてそれをWebImageクラスの配列に変換して返します。また、「次へ」のリンク文字列の有無をチェックしてhasNextフィールドを設定します。
MoveNextメソッドでは、次のページがあればcurrentPageフィールドを1進め、なければ何もしません。GetImagesメソッドを呼び出して検索結果を取得し、次にこのメソッドを呼び出してfalseが返ってくれば、それ以上は検索結果がないことになります。
public bool MoveNext()
{
if (hasNext)
{
currentPage++;
}
return hasNext;
}
|
Public Function MoveNext() As Boolean Implements WebImageLibVB.IWebImage.MoveNext
If _hasNext Then
_currentPage = _currentPage + 1
End If
Return _hasNext
End Function
|
|
IWebImageインターフェイスのMoveNextメソッドの実装(上:C#、下:VB.NET) |
Nameプロパティは、単にメイン・ウィンドウのコンボボックスに表示される表示名を返すだけです。
public string Name
{
get { return "Google"; }
}
|
Public ReadOnly Property Name() As String Implements WebImageLibVB.IWebImage.Name
Get
Return "Google"
End Get
End Property
|
|
IWebImageインターフェイスのNameプロパティの実装(上:C#、下:VB.NET) |
Resetメソッドはオブジェクト内部の状態を初期化するメソッドです。このクラスのコンストラクタでは、このResetメソッドを呼び出してフィールドを初期化します。
public void Reset()
{
hasNext = false;
currentPage = 0;
}
|
Public Sub Reset() Implements WebImageLibVB.IWebImage.Reset
_hasNext = False
_currentPage = 0
End Sub
|
|
IWebImageインターフェイスのResetメソッドの実装(上:C#、下:VB.NET) |
ほかのメソッドやプロパティについてはソース・コードを参照してください。WISGoogleプロジェクトをビルドするとGoogle用プラグインであるWISGoogle.dllが出来上がります。
■Google用プラグインのテスト
以上で完成ですが、このままではつまらないので、次のような簡単なテスト・クラス(GoogleTestクラス)を追加して、実際に動かしてみましょう。このクラスはGoogleImageクラスと同じファイルに記述します。
public class GoogleTest
{
static void Main()
{
string query = "c#";
IWebImage google = new GoogleImage();
do
{
foreach (WebImage wi in google.GetImages(query))
{
Console.WriteLine(google.CurrentPage);
Console.WriteLine(wi.SmallImageURL);
Console.WriteLine(wi.LargeImageURL);
Console.WriteLine(wi.DetailPageURL);
}
} while (google.MoveNext());
}
}
|
Public Class GoogleTest
Shared Sub Main()
Dim query As String = "c#"
Dim google As New GoogleImage
Do
For Each wi As WebImage In google.GetImages(query)
Console.WriteLine(google.CurrentPage)
Console.WriteLine(wi.SmallImageURL)
Console.WriteLine(wi.LargeImageURL)
Console.WriteLine(wi.DetailPageURL)
Next
Loop Until google.MoveNext() = False
End Sub
End Class
|
|
Google用プラグインをテストするためのコード(上:C#、下:VB.NET) |
そして、プロジェクトのプロパティを開き、次の画面のように「出力の種類」を、[クラス ライブラリ]から[Windowsアプリケーション]に一時的に変更します。そして実行すれば、このMainメソッドのWriteLineメソッドによる出力がVS.NET内の[出力]ウィンドウに表示されます。
 |
プロジェクトのプロパティ(画面はC#の場合) |
コードにMainメソッドを追加し、「出力の種類」を[クラス ライブラリ]から[Windowsアプリケーション]に変更することによりEXEファイルが作成され、単体で実行できるようになる。またVS.NETでは、出力の種類を[Windowsアプリケーション]にすると、コンソール画面への出力はVS.NETの[出力]ウィンドウに出力される。 |
[出力]ウィンドウには画像やページのURLがだらだらと表示されれば成功です。各URLは、[CTRL]キーを押しながらマウスで左クリックすれば、VS.NET内に画像やページが表示され、それらが正しいリンク先となっているかを確認できます。
 |
Google用プラグインのテスト実行結果 |
[出力]ウィンドウには画像やページのURLが表示されていく。この画面はその1つを[CTRL]キーを押しながらマウスで左クリックし、URLが示す画像を表示したところ。 |
今回はGoogle用プラグインを作成しましたが、同様の手順によりIWebImageインターフェイスを実装したクラスを作成すれば、別の検索サイトに対応したプラグインも作成可能です。このようにして作ったDLLファイルは、実行ファイルのみのzipファイルに含まれているWebImageSearch.exeのあるディレクトリにコピーすれば、アプリケーション(WebImageSearch.exe)から使えるようになるはずです。時間があったら試してみてください。
■
さて次回は、拡大/縮小可能なサムネイル画像を並べて表示する、本アプリケーションのコアともいえる「サムネイル・ビューア・コントロール」を作成します。これはほかのアプリケーションでも流用できるように独立したコントロールにする予定です。お楽しみに。