2011/11/05

FreeImage

・・・というわけで、前回、
System.Drawing.BitmapはJPEGの画質が悪すぎる
ということが判明したので、
その代わりに使えそうなものを探してみたわけです。

まず、最初に見つけたのが

「libjpeg」(IJG JPEGライブラリ)
公式サイト http://www.ijg.org/

が、調べてみると、どうも、
・Cで書かれたソースコードで配布されている。
・プログラムに直接ソースコードを組み込んで使うのが、もっぱらの利用法。
・DLLにできなくもないが、なかなかに面倒らしい。
・誰かDLL作ってバイナリ公開してないかな-、と思ったが見つからない。
・そんなこんなで、.NETで利用するのも難しそう。
というわけで、ひとまず諦める。

そして見つけた第2候補。

「FreeImage」
公式サイト http://freeimage.sourceforge.net/

・オープンソースなライブラリ。
・PNG, BMP, JPEG, TIFF, など、いろんなフォーマットに対応している。
・Windows, Linux, Mac OS X などの各OSに対応。32bit、64bit両方に対応。
・C, C++, VB, C#, Delphi, Java, Perl, Python, PHP, TCL, Ruby, と対応言語はよりどりみどり。
・使い方が簡単(らしい)。
・C#でのFreeImageの使い方とかを説明してくれているような日本語のサイトをgoogle先生は知らないようだ。(英語でもほとんど無いっぽい。)

.NETから使えそうなので、
とりあえずいじってみよう、ということでダウンロード。

で、結論から言うと、
これはなかなか良さそうです。
使い勝手も良いし、機能も豊富です。
ちゃんとJPEGを本来の画質で読み込めるし、
読み込んだ画像をSystem.Drawing.Bitmapのインスタンスとして取得したり、
逆にSystem.Drawing.BitmapのインスタンスをFreeImageのAPIで
いろんなフォーマットでファイルに書き出したりもできる。

以下、ダウンロードしたFreeImageの使い方など。

ダウンロードしたのは
"FreeImage3151Win32.zip" というファイル。
解凍されたファイルの中には、
"Wrapper\FreeImage.NET\cs\"フォルダ内にVisualStudio2005のソリューションファイルが。
これをVisualStudio2010で開くとプロジェクトの変換が行われるが、特に問題なく変換される。

が、ビルドしようとするとうまくいかないので、多少設定をいじる必要有り。

まず、"Library.2005"というプロジェクトのプロパティを開き、
「ビルド」タブの「警告をエラーとして扱う」という項目で「すべて」が選択されているので、
それを「なし」に変更。

同じく、"Library.2005"プロジェクトに、ソリューションエクスプローラーでコンテキストメニューから
「追加」 - 「既存の項目」で、
解凍されたFreeImageのフォルダに入っている
"FreeImage\Dist\FreeImage.dll"を追加。
これがネイティブなFreeImageのライブラリ。
(で、今ビルドしようとしているのが、このDLLのラッパー。)

最後に、ソリューションに"UnitTest.2005"というプロジェクトが含まれているので、それをソリューションから削除。

これでビルドができるはず。
サンプルがたくさん入っているので、
それを見れば、必要そうな使い方も一通りわかるはず。
シンプルなAPIになっていて、割と簡単そうです。


今回は、このあたりで。
日本語の情報が少ないようなので、
そのうち、まとめ直したりしてHPのほうにUPしておこうと思います。

2011/10/26

System.Drawing.BitmapのJPEGは画質が悪い。

いまさら気づいたのだが、
表題通り、
.NET FrameworkのSystem.Drawing.Bitmapで
JPEG形式の画像を読み込むと、
けっこう画質が劣化した状態になる。

気づいたきっかけは、
グレースケールなJPEGの画像を読み込んでレンダリングしようとしたとき。
下の画像のように・・・orz


左が、System.Drawing.Bitmapで読み込んだもの。
右は、GIMPで読み込んだもの。

こんなんじゃ使えねぇべ。

カラーの画像でも、これほどはっきりとしたものでは無いが、画質が悪い。

詳しくは、ここや、
http://kerokero.org/blog/blog.cgi/permalink/20101009031415
ここ
http://tete009.seesaa.net/article/143418763.html
の方々が詳しく調べていらっしゃるようです。
さて、どうしたものか・・・。

2011/04/03

COWON S9 のプレイリスト

普段、COWON S9 を使っているのだが、
プレイリストとして .m3u ファイルを適当なソフトで作成して
それをそのままS9に放り込んでも、
なぜかS9がうまく読み込んでくれないことが多いようで。

調べてみると、なんか
S9が認識してくれる.m3uのフォーマットが微妙(?)なのが原因のようで、
ちょいと変換ツールを作ってみました。

・・・まぁ、
S9は発売してからしばらくたってるし、
新機種も出てるし、
それほど需要はないとは思いますが。

詳しくはこっちにて。
http://sky.geocities.jp/freakish_osprey/Software/software_convm3u.html

2011/02/24

.NET用のオープンソースなHTMLのパーサー : Html Agility Pack

かくかくしかじかでHTMLの解析をする必要があったのでけれど、
.NETにはXMLのパーサーはあれどもHTMLのパーサーがないので
なんかいいものがないかと探していたところ、
なかなか良さげなツールを見つけたのでそのメモ。

ちなみに、
System.Windows.Forms.HtmlDocument ってのもあるけれど、
WebBrowserコントロール経由でないとインスタンスを取得できないとか、
InternetExplorerに依存しているとか、
InternetExplorerのバージョンによって影響されるとか、
HTMLの文字列だけほしいのに画像までダウンロードしてくるので遅くて重いとか、
まぁ、もろもろの問題があるので使えない。

で、今回の本題はこっち。
Html Agility Pack
http://htmlagilitypack.codeplex.com/

.NET向けのHTMLパーサーです。
オープンソースでフリーのライブラリ。

使い方について
あんまり情報が見つからなかったので
その辺について。

まずはじめに1つ。
using HtmlAgilityPack;
と書くと、
System.Windows.Forms.HtmlDocument と曖昧な参照になってしまい
コンパイルエラーになるので、
using hap = HtmlAgilityPack;
とかしておいた方がいい。

基本的に、HTMLの解析には、
HtmlAgilityPack.HtmlDocument
というクラスを中心に使用します。

HTMLのソースは、たとえばこんな感じで取得する。
System.Net.WebClient web = new System.Net.WebClient();
string htmlSource = web.DownloadString(url);
ほかにも、ブラウザでソースを表示させてコピペとかいろいろ方法はある。

HtmlAgilityPack.HtmlDocument html = new HtmlAgilityPack.HtmlDocument();
html.LoadHtml( htmlSource; );

これだけで、ソースのロードは完了。

html.Load( url );
で、URLからダウンロードしてくることも出来るっぽい。

あとは、XPathという、XMLの特定の要素を指定したりするための言語を使って
目当ての要素を取得する。
XPathの詳細はgoogle先生に任せるとして、

HtmlAgilityPack.HtmlNodeCollection tags = html.DocumentNode.SelectNodes( xPath );
とすれば、該当するタグのコレクションが取得できる。

XPathは、たとえば、

HtmlAgilityPack.HtmlNodeCollection ulNodes = html.DocumentNode.SelectNodes( "//ul" );
とすれば、ページ内の
<ul> ~</ul>
でくくられた部分を一通り取得する。
さらに、

HtmlAgilityPack.HtmlNodeCollection liNodes = ulNodes[0].SelectNodes( ".//li" );
とすると、最初の<ul></ul>内の
<li></li>要素のコレクションが取得できる。

HtmlAgilityPack.HtmlNode li = html.DocumentNode.SelectSingleNode( "//ul[1]/li[2]" );
で、1つめの<ul></ul>内の
2番目の<li></li>要素を取得したりとか、

HtmlAgilityPack.HtmlNode td = html.DocumentNode.SelectSingleNode( "//table[1]//td[3]" );
で、1つめの<table></table>内に出現する3つめの<td></td>を取得したり。

HtmlAgilityPack.HtmlNode a = html.DocumentNode.SelectSingleNode( "//a[0]" );
string linkUrl = System.Web.HttpUtility.HtmlDecode( a.GetAttributeValue( "href", "" ) );
で、ハイパーリンクのアドレスを取得したりもできる。

逆に、
HtmlNode.XPathプロパティからXPathを取得することもできる。

つまるところ、XPathをうまいこと指定してやることで、
簡単にほしい情報をHTMLから引っこ抜いてこれる。

2011/01/25

Windows Live Mail が起動しない...

唐突に、Windows Live Mail が起動しなくなった...orz
起動すると、ウィンドウが開いた直後に落ちる。
一瞬だけウィンドウの中身が表示されて、
直後にウィンドウ内が真っ白になり、
「Windows Live Mail は動作を停止しました」とメッセージが。
それ以外はエラーメッセージも何もない。

・・・と思ったら、何度も起動を試してみると、
たまーに何事もなく起動したりもする。
何が起きているのやら。

Webで検索してみると、
Windows Update が、なんかよからぬことをしてる、
っていうのがすぐに見つかったので、
その噂の "KB2454826" を探してみたが
更新プログラムの履歴にはそんなのないですよ...?
最近インストールされたとおぼしき更新を
アンインストールしてみても、改善しない。


まぁ、Gmali をメインに使ってるから、
Windows Live Mail なんぞぶっ壊れても、
何とでもなるっちゃなるんだけど・・・。