3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。(jehupc.exblog.jpから移転中)

IE8でJPEG画像を表示して保存しようとするとビットマップになる時がある

IE8の環境で、JPEG画像へのリンクを押下して表示された画像を保存しようとすると、保存形式がビットマップしか選べなくなることがあります。(保存時のファイル名も untitled.bmpになってしまいます)

この現象についてちょっと調査してみました。

ググると同様の現象の解決法があったんですが、大抵はキャッシュの削除や、Temporary Internet Files の場所を変えるという方法でした。

キャッシュの削除や場所を変えても改善しませんでした。

で、現象が発生する時と発生しない時があるので、どういう条件でそうなるのか色々試したところ、日本語のファイル名のリンクを押下するとビットマップOnly現象が発生することがわかりました。

(グループウェアで画像ファイルを添付してのやり取りがあるんですが、日本語のファイル名をそのままアップするケースが多い状態です)

その点について更に情報収集していると、MSフォーラム:IE8で日本語ファイル名の画像について名前をつけて保存しようとすると untitled.bmp になり bmp でしか保存できないで望んでいた答えが出ていました。

どうやら、URLとキャッシュのファイルのマッピングテーブルである index.dat (C:\Documents and Settings\ユーザ名\Local Settings\Temporary Internet Files\Content.IE5\) へのアクセスするAPIの問題だそうです。

ファイルをキャッシュする時 SetUrlCacheEntryInfo 関数を使って保存し、ファイル名をUTF8でindex.datに格納します。

そして、画像ファイルを右クリック→名前をつけてファイルを保存 にすると、RetrieveUrlCacheEntryFile 関数でキャッシュされたファイルを得ようとするわけですが、ファイル名がShift-JISで渡されてしまい、RetrieveUrlCacheEntryFile内部ではindex.datにそんなファイル名はねーよ (実際はUTF8で格納されているため)となって、エラーとなり、仕方なくメモリの中に展開されたビットマップオブジェクトをuntitled.bmpとしてビットマップ保存しようとするようです。

ファイル名がURLエンコードされている場合、保存時はちゃんとJPEGで行おうとします。(おそらくRetrieveUrlCacheEntryFile関数内でURLデコードしてキャッシュを見つけることができるのでしょう)

ただし、保存時のファイル名が短い名前(8.3形式)になってしまいます。(これもIEのバージョンによって挙動が異なるようです。IE8以降では短い名前ですが、IE7以前はURLエンコード名そのままになるようです。このあたりの話はMSフォーラム:キャッシュに非ascii文字のファイル名のゴミが残るでまとめられています)

結局、MSがAPI(RetrieveUrlCacheEntryFile関数)を直さないといけないので、ユーザに画像ファイルを保存する用途の場合、IEで日本語を含む画像ファイルを扱わないほうが良さげですね。

どうしてもという場合は、サーバ側でjpegファイルの場合は Content-Disposition を attachment にし、Content-Type を application/octet-stream にすることで、JPEGへのリンク押下時にファイルのダウンロードダイアログを表示させることができます。ファイルのダウンロードダイアログから保存した場合はJPEGで保存されます。

この設定はWebサーバ側で、JPEGMIMEを変えてしまえばいいだけの話です。

参考:

MSサポート:Internet Explorer で画像がビットマップ (.bmp ファイル) として保存される ここではキャッシュフォルダ関連の設定とアドオンを見直すようにとあります。