

昨年あたりいくつかのWebサービスが発表されてから国内でも使われる事例が増えてきました。伊藤 将雄さんのSimple APIを先駆けに、いくつも提供されています。Webページスナップショット比較サイト、キャプチャを極める完全ガイド
実際にだしてみるとこんな感じです↓(By HeartRails)
Webページを画像やPDFとして変換する機能への需要は多くあります。外部ページへのリンクにマウスを合わせると飛び先のサムネイルが表示されるなどは、良い使い方だとおもいます。検索エンジンの結果にサムネイルを使っている場合もあります。
動的にリンク先を生成するWebアプリケーションの場合、任意のWebページのスナップショットをプログラムでリアルタイムに生成する必要があります。外部のWebサービスを使うのでは少し不安になります。プログラマであれば、自前プログラムからWebページサムネイルを生成できるようにしたくなります。
Webページサムネイルのプログラム開発アプローチは3通りあります。
方法1
正攻法は、HTMLをPersingして、レンダリングする方法です。ゼロからHTMLレンダリングエンジンを開発するのは、ワクワクと胸が躍ります。しかし、サムネイルを作成するためにだけHTMLレンダリングエンジンを自製してしまうのは、モッタイナイですよね。ですので、GPLで公開されているFireFoxのGecko HTMLレンダリングエンジンを再利用する方法があります。ゼロからスタートしても3ヶ月くらいあれば開発できるでしょう。
方法2
もっと手を抜く方法は、IEコンポーネントを再利用することです。.NetであればWebBrowserコントロール(実体はIEのCOMオブジェクト)を使う方法です。Microsoft社製ですのでソースコードは開示されていませんが、IEのほとんどの機能はCOMインターフェイスを通じてプログラムから制御可能です。パフォーマンスを要求しなければ1週間程度で開発できます。
方法3
さらに手を抜く方法としては、コマンドラインで動くWebページキャプチャツールを使う方法です。例えば、CrenaHtml2Jpgやurl2jpgなどです。こちらで実装した方がいますが、毎分10ページ程度だそうです。これなら半日で作れますね。url2jpgは方法2で作られているので、実際は方法2の手抜きバージョンですね。
ちなみに、HeartRailsでは方法1(Embedding Mozilla)を採用しているようです。
私は、方法2を試してみました。まだ、安定していないのでアプリを公開しませんが、単発で動作させるのは問題ないですが、マルチスレッドで動作させると落ちます。
IEのCOM周りにRe-entrantになっていない部分があるようで、手がでません。IE6、IE7と試してみましたがエラーがでるので、根本的にSTAモデルに対応してない資源管理している可能性があります。マルチプロセスでの処理はまったく問題ないので、どこかスレッドもでるがおかしそうです。
メール送信に利用するSMTPサーバがPOPBeforeSMTPで認証をしているケースが少なくありません。
この場合、POPサーバに対して認証を実施する必要がありますが、Microsoft .NetのSystem.Net.MailはSMTPClientのみで、POPClientがありません。
TCPClientを使って直接POPサーバにメッセージを送信してもよいですが、POPClientの認証ライブラリがほしいところです。
TKMP.dllを使えば解決できるのですが、GPLでしたので再配布する目的では利用できません。
アジルテックでは、自前のPOPClientを利用しています。非商用利用向けにβ公開していますので、ご利用ください。
標準の .Net Frameworkの中にQRコードを生成するライブラリがありません。
最近ではWebサービスでQRコードを生成してくれるサービスもありますが、QRコードの生成機能などは外部サービスを使うよりも、自前のサーバで生成したほうがサーバの信頼性が高まります。
世にあるQRコード生成ライブラリをまとめてみました。いくつも製品・フリーソフトがあるので適切なものを選んでください。
| 製品名 | 会社 | 価格・ライセンス形態 | コメント |
| QRGen | アジルテック | 個人利用無料、商用利用には商用ライセンス15,000円 | 弊社のライブラリです。ご要望などありましたら連絡ください |
| QR_Encode | スパイシーソフト | フリーソフト、アプリ同梱の再配布OK。単体での再配布は禁止 | 基本機能のみ提供。出力QRコードのタイプが02に固定 |
| BarCode.Net | (有) パオ@オフィス | 1ユーザライセンス18,900円。CompornentSourceだと18,480円。サーバライセンスは記述なし | ソースコードを含めて購入することができる |
| ColorfulQRCodeMaker DotNetBarcode |
個人 | 再配布条件:本アプリの利用を明示すること。Webアプリについては「対応していない」と明記されているが、実際には利用できるが、Webで利用するとライセンス違反の可能性がある。著作者からWebでの利用ライセンスを確認する必要がある | 色表現が多彩 |
| ActiveReports for .Net Professinal Edition |
Data Dynamics | 再配布ライセンス 294,000円 | 画像処理ライブラリの一環としてQRコード生成機能を提供している。高機能すぎる |
| LEADTOOLS 2D QR Code Barcode Modules | Lead Technologies | 再配布ライセンス147,000 + 210,000円 米国 995$。サーバライセンスは記述なし | 高機能すぎてWeb利用には不向き |
まとめ:
個人で利用するならばQRGenかQR_Encodeがオススメです。Webアプリケーション用の商用ライセンスが必要な場合は、QRGenをご購入を検討ください。
先日、RFC違反のメールアドレスに関する記事を書きましたが、ASP.NETのライブラリはGlobal基準(またはMicrosoft基準)のため、ガラパゴス進化をしている日本のネット環境と乖離していることがあります。
System.Net.Mailはその中でも際立っていて、海外ではUTF-8 & Qエンコードが主流なため、国内のShift-JIS & Bエンコードという日本のネット環境に適合していません。
悩まれている方も多く、あちらこちらで記事があがっています。
System.Net.Mail問題その3(中の技術日誌)
せっかくsubjectとbodyにはエンコード方式の指定があるにもかかわらず、From, To, Cc, Bcc, ReplyToなどのこのMailAddressクラスにはエンコード方式を指定する方法がありません。
結局、MailAddressクラスのコンストラクタが「送り先氏名 <user@address.com>」という文字列を解釈して処理してくれるにもかかわらず、Qエンコーディングなため、自前でBエンコード処理をして2つ変数をとるコンストラクタ MailAddress( address, displayname) を呼ぶ必要があります。
string from_name = MyBEncode( "株式会社 アジルテック", enc );
string from_address = "user@address.com";
msg.To.Add( new MailAddress( to_address, to_name ) );
また、Subject, Bodyのエンコードを指定できますが、iso-2022-jpに指定しても、
Subject: =?iso-2022-jp?Q?=1B$B%5%V%8%'%/%H=1B(B1?=
Content-Type: text/plain; charset=iso-2022-jp
Content-Transfer-Encoding: 8bit
出力はSubjectはQエンコードされ、BodyのContent-Transfer-Encodingは8bitエンコーディングです。
結局、せっかく自動処理してくれるSubjectもMailMessage.SubjectEncodingは未指定にし、自前でBエンコーディングをする必要があります。
Bodyを7bitにするには、Content-Transfer-Encodingについては、msg.HeadersにAddしても追加されず、AlternateViewを使って7bitエンコーディングを実現する必要があります。
追加されない:
msg.Headers.Add( "Content-Transfer-Encoding", "7bit" );
AlternateViewを利用する:
byte[] buf = enc.GetBytes( body );
MemoryStream mem = new MemoryStream( buf );
AlternateView alt_msg = new AlternateView( mem, new ContentType("text/plain; charset=" + enc.BodyName ) );
alt_msg.TransferEncoding = TransferEncoding.SevenBit;
これまでは上記の方法でも、「content-transfer-encoding: 7bit」と出力するところが、「content-transfer-encoding: sevenbit」となっていたため、正しく送信できなかったのですが、.Net Framework 2.0 SP1で、「[FIX] System.Net.Mime 名前空間または System.Net.Mail 名前空間を使用する Visual Studio 2005 プログラムを実行すると、TransferEncoding プロパティの値が正しくないことがある」修正が含まれたので、SP1以降は送信するこができます。
参考:
[.NET 2.0]日本語(ISO-2022-JP) を Content-Transfer-Encoding: 7bit で送信する方法
上記の方法で大部分は問題なく動作するが、まだ問題が残っています。RFC 2047に記述のあるエンコード行の76文字改行規制です。
encoded-word = "=?" charset "?" encoding "?" encoded-text "?="
複数の行からなるヘッダフィールドの長さに制限はないが、1つ以上の
'encoded-word' を含むそれぞれの行は、76文字に制限される。
改行いれた文字列を渡すと、MailMessageのSubjectプロパティもMailAddressクラスコンストラクタもエラーを発生します。
2バイト文字だと40文字越えるとこの制限に抵触します。
=?iso-2022-jp?B?GyRCJTUlViU4JSclLyVIRDkkJCU1JVYlOCUnJS8lSCRAJEgkSSQmJEokayRzJEckNyRnJCYkKyRKIzEjMiMzIzQjNSM2IzcjOCM5IzEjMiMzIzQjNSM2IzcjOCM5GyhCQUJDREVGRxskQiQiJCQkJiQoJCokKyQtJC8kMSQzJDUkNyQ5JDskPSQ/JEEkRCRGJEghIktcRnwkT0AyRTckSiRqGyhC?=
しかし、上記のような長いエンコード文字列を渡しても大丈夫なSMTPサーバ、メールクライアントも多いようです。Au, Softbankは76文字で区切らなくても表示できる端末があるので、少なくとも両社のSMTPサーバは受け取ります。(ただし、端末によっては表示されない可能性あり)
まとめ:
RFCの作法は守りたいという方は、Socketから直接SMTPサーバと通信してください。
[追記 2008/11/20 ] 弊社より、サブジェクト文字化けとRFC非準拠アドレスに対応したSMTPClientを公開しました。現在、β公開につき無料で利用できます。ぜひお試しください。
問題:
System.Net.Mail.MailAddressクラスは携帯各社が許可している、RFCに準拠しないメールアドレスを渡すことができません。
MailAddress address = new MailAddress( "test...@docomo.ne.jp" );
上記のようなメールアドレスを渡そうとするとFormatExceptionが発生してしまいます。
System.FormatException はユーザー コードによってハンドルされませんでした。
Message="指定された文字列は、電子メール アドレスに必要な形式ではありません。"
Source="System"
StackTrace:
場所 System.Net.Mime.MailBnfHelper.ReadMailAddress(String data, Int32& offset, String& displayName)
原因:
System.Net.MailAddressがRFCで定められているよりも厳しくメールアドレスの形式をチェックしているため。
実はこのようなRFC準拠していないメールアドレスであっても「"test..."@docomo.ne.jp 」とアカウント部分をエスケープすることでRFC準拠として扱えるのですが、MailAddressクラスはFormatExceptionを発生させます。
解決方法:
ASP.NET開発で携帯メールアドレスを扱うことは多々あり、「RFC非準拠アドレスにメール送信できないのは仕様です」といっても発注元が検収してくれません。
そこで、簡単な逃げ道としては.Net Framework 1.1で使われていたSystem.Web.Mailを利用する方法があります。
MailMessage msg = new MailMessage();
msg.To = "test...@docomo.ne.jp";
MailMessageクラスのToプロパティはstring型でメール形式をチェックしません。どんな文字列でも渡すことができます。また、OSが日本語環境であれば、デフォルトのエンコーディングはiso-2022-jp かつ Bエンコードになるので、特に設定せずとも各携帯キャリア対応です。
いいことずくめに思えますが、下記のような問題点があります。
- 実行環境依存が発生する
- CDOモジュールが.Netプログラマにわかり難い
- HTMLメール送信機能が不十分
- SMTP/SSLが使えない
ひとつひとつ詳しく解説します。
1 実行環境依存が発生する
System.Web.Mailのメール送信はMicrosoft CDO for Exchange 2000のモジュールを利用しているため、実行環境によって挙動が変化します。本番環境でモジュールがなくて動かない・・・ということもありえます。
アプリケーションの実行アカウント権限がCDOオブジェクトにアクセスできないとアウトです。あちらこちらの掲示板で質問があがっては未解決という状態です。
特定のVersionのVisual Studioをインストールしたり、Exchange Serverをインストール&アンインストールしていると症状がでるといった報告もあります。
2 CDOモジュールが.Netプログラマにわかり難い
この自由度の高かった1.1のSystem.Web.Mailが2.0でSystem.Net.Mailに置き換えられているのは、基本的にSystem.Web.MailはExchangeモジュールの.Net用ラッパークラスにすぎないためです。細かい制御は全て、CDOに対するメッセージを付加する必要があります。たとえば、portを25番以外に変更する場合には、MailMessageのFilesプロパティにCDOの設定をメッセージとして追加する必要があります。
msg.Fields[
"http://schemas.microsoft.com/cdo/configuration/smtpserverport"] = 25;
また、CDOのエラーメッセージが不親切で、原因の切り出しがし難い点があります。
参考:
「CDO.Message」を作成しなかったための」エラー メッセージのトラブルシューティング方法
3 HTMLメール送信機能が不十分
msg.BodyFormat = MailFormat.Html;
上記のプロパティを設定することでHTMLメールを送信することができるのですが、機能的に不十分です。携帯のデコメール等はimgタグで指定するsrc属性を外部リソースを指定することができません。そのため、添付ファイルを表示するためにContentIdを指定したいのですが、System.Web.Mail.MailAttachmentにはContentIdを指定できません。をまた、HTMLメールを指定した際の、Textメールは自動生成なので、HTMLとTextメールをそれぞれ整形して指定できません。
参考:
DoCoMo デコメ
KDDI デコメ
SoftBank
4 SMTP/SSLが使えない
SMTP/SSLをサポートしていないようです。CDOの設定を探せばあるのかしれませんが、ドキュメントを発掘できません。SMTPAuthはサポートしているのですが、平文 or NTLM(=CRAM-MD5 )となり、ベストエフォート設定はできません。ちなみにSMIME署名はCAPICOMを使うのが常道なので、1.1、2.0いずれのVersionでもサポートしていません。
参考:
[Microsoft]System.Web.mail を使用している 有効 SMTP 認証の方法
[MSDN] リファレンス http://schemas.microsoft.com/cdo/configuration/
総括:
「入会案内程度のメールであればSystem.Web.Mailは利用に耐える」、セキュリティに執着しない顧客で、メルマガのようにHTMLメールが不要なケースであればSystem.Web.Mailでも十分です。しかし問題点1で指摘したように、テスト環境では動いてたものが、本番環境によってCDOモジュールが見つからないというエラーがでて顧客のクレームを浴びることもありえます。必ず、CDOモジュールが動作するかミニプログラムを本番サーバで動かして確認してください。
弊社ではSMTPは、System.Net.MailもSystem.Web.Mailのどちらも使うことを辞め、自前で実装したSMTPクライアントを利用しています。顧客からの要望に細かく対応できるので便利です。
[追記 2008/11/20 ] 弊社より、サブジェクト文字化けとRFC非準拠アドレスに対応したSMTPClientを公開しました。現在、β公開につき無料で利用できます。ぜひお試しください。

