HaskellでTwitterクライアント開発blog(仮)

今すぐに挫折するかもしれない程度のモチベーションによるTwitterクライアント開発記

アイコンを表示(Twitterアイコンを取得→表示)

かなり空きましたが、投げたわけではないですよ?
大学始まったので忙しいのです。

さて、何をやっていたかというと、ちょっと混沌とし始めたコードを若干整理したのと、今まで改行だけでダラーッと一つのStringをプリントするだけだったタイムライン表示を、個別の領域に割り当てて表示するようにしました。

 

で、ここまで出来たのだから、そろそろ絵的に映えるものが欲しいと思い、アイコン画像を取得して表示するようにしました。

f:id:xenophobia:20120516033134p:plain

 まず、画像の取得はおいておいて、画像がファイルにあった場合。
画像の表示は、流石にファイルをそのまま表示することは出来ませんが

ファイル名からPixBufを作成→それを描画

という簡単な処理で済みます。

ファイル名からPixBufを作成するのは

Graphics.UI.Gtk.Gdk.Pixbuf.pixbufNewFromFile :: FilePath -> IO Pixbuf

で行い、PixBufの表示は

Graphics.UI.Gtk.Gdk.Drawable.drawPixbuf :: DrawableClass d => d -> GC -> Pixbuf -> Int -> Int -> Int -> Int -> Int -> Int -> Dither -> Int -> Int -> IO ()

で行います。

 

後者の関数がちょっとわかりづらいですね。このページ

http://d.hatena.ne.jp/kakurasan/20100319/p1

のコード例が、言語は違えど役に立ちました。(gtk2hsのバージョンにはDither型の引数が追加されています)

引数の意味はそれぞれ

drawPixbuf ::
(d: 描画ウィジェット)
(GC: グラフィカルコンテキスト)
(Pixbuf: 表示する画像のPixbuf)
(Int Int: 画像の切り取り開始位置の座標)
(Int Int: 描画領域の描画開始位置の座標)
(Int Int: 画像から切り出す大きさ)
(Dither: ディザリングの指定。None, Normal, Maxから選べる)
(Int Int: 表示する領域の大きさ。-1を指定すると画像の大きさと同じになる)

となっているようです。

 

画像を表示させる処理はこれでいいとして、問題はその表示させるファイルを取得する部分で、これは当然ダウンロードして手に入れることになります。
各々のツイートには発現者のアイコンのURLが入っているので、これにアクセスして画像を手に入れればいいわけです。

 

いままで画像をローカルにダウンロードするプログラムを書いたことがなかったのですが、「ネット上から複数の画像ファイルをダウンロードする」というプログラムにはいいサンプルがありますね。どんな言語でもたいてい誰かがこのプログラム書いてます。

 

いかにしておっぱい画像をダウンロードするか~2012 Haskell

http://d.hatena.ne.jp/D_Rascal/20120320/1332244651

 

はい。並列化もしてますし、かなりいいサンプルですよね。

Conduit版もあったような気がしましたが、普通にNetwork.HTTPでやることにしました。

 

で、これでいいんですが、いちいちアイコン画像を全部ダウンロードしてくるのは明らかに重いので、URLをハッシュテーブルに保存して一回ダウンロードした画像はローカルに保存したものを使うようにしました。

さらに、ローカルに保存したアイコンは消さないでおき、前回起動時に保存したアイコンがあればそれを使うようにしました。(しかしこれだと、アイコンがいつまでたっても積もり積もってしまうことになるので、そこは後で考えなければならない所)

この部分のコードはこんな感じ

これでアイコンが表示できるようになりました。

今回までのコード

https://github.com/xenophobia/hshstter/tree/660407074e297412b090d0e0a85c0ca2a66f9f29

 

なお現在、RT・ふぁぼの機能を実装しようとしていて、その手前のGUIまわりで詰まってる所です。
できたら記事書きますが。