今回は Rails で画像ファイルをアップロードする方法を調べてみました。これは、自然観察のフィールドノートを写真付きで管理するアプリには必須の機能です(そんなソフトは作らない?)。
file_column Plugin をインストール
ネットをググッてみたら、file_column なるプラグインが良いらしい。というか、殆どデファクト・スタンダードです? これ一つでファイルのアップロード、表示から、リサイズまでこなしてくれるみたいです。これは、RMagick を利用するらしい。で、RMagick は、ImageMagick の Ruby 用ラッパー(?)です。ということは、
- ImageMagick をインストール
- RMagick をインストール
- file_column Plugin をインストール
しかしめげずに、それぞれの最新版を落としてきて入れたところ、見事エラーが表示され、動きませんでした。
むむむ。むむむむむ。さらに調べる。
答えは、RMagick ページのFAQに、ありました。
I've got a version of ImageMagick for Windows that is more recent than the bundled version. Can I use it? No. You must use the ImageMagick Windows installer that is bundled with RMagick even if a later version is available from ImageMagick. RMagick will not run if you try to use a different version. |
指示に従って、RubyForge の RMagick プロジェクトページから、無難そうな RMagick-1.14.1_IM-6.3.0-7-Q8.zip を落としてきます。
解凍して、README.HTML を読みます。
なになに。
まず、"ImageMagick のインストーラを起動せよ。Update executable search path.オプションをチェックだぞ。あとのオプションはお前に任せる"、か。ラジャーっす。
ここにも、"他バージョンの ImageMagick は使うでない"と書いてあります。
続いて、RMagick のインストールです。こちらは gem を使います。
gem install rmagick --local |
やれやれ。ようやく本題の file_column Plugin の番です。
が、これは簡単。お馴染みの RadRails で、Rails Plugins タブを選び、file_column Plugin を選択してインストールすれば完了です。
file_column Plugin を使ってみる
環境を整えるまでにちょっとありましたが、これで使えるようになりました。早速、画像ファイルのアップロード機能を実現しましょう。ああ、その前に一つ確認事項です。
file_column Plugin では、画像ファイルは所定のディレクトリに入れられ、テーブルには画像ファイルへのパスが保存されます。まあ、一般的な方式ですね。
では、テーブルに、パスを保存するフィールドを追加しましょう。
今回は、pictures テーブルに String 属性の image という名前のフィールドを作りました。
RadRails で、/app/models/picture.rb を開き、次のように書き加えます。
class Picture < ActiveRecord::Base file_column :image, :magick => { :versions => { :thumb => "100x100", :middle => "200x200", :large => "800x800" } } end |
見ての通り、オリジナル画像の他に、"thumb"、"middle"、"large"という3種類のサイズの画像も保存します。これは別に3種類じゃなくても、また、名称もサイズも自由に設定できます。
リサイズには RMagick(ImageMagick) が使われます。ジャギーが目立ちませんので、リサイズメソッドはバイリニアかバイキュービック法でしょうかね。済みません、調べていません。
view にアップロード機能を付け加えるのも簡単です。
<form action="create" method="post" enctype="multipart/form-data"> <p> <b>画像ファイル:</b><br /> <%= file_column_field "picture", "image" %> </p> <p><input type="submit" value="アップロード" /></p> </form> |
<%= image_tag url_for_file_column(@picture, 'image') %> |
<%= image_tag url_for_file_column(@picture, 'image', :thumb) %> |
いやぁ、実に簡単にアップロード機能が実装できました。アップロード時に、拡張子、ファイルサイズ、画像サイズなどのバリデーションも可能です。小さすぎる画像や大きすぎる画像をハネるのも簡単ですね。
日本語のファイル名を使えるようにする
と、ここまでは良かったんですが。……2バイト文字のファイル名が使えません。漢字はアンダーバーに置き換えられてしまいます。日本語のファイル名は色々と問題を起こすから、ここは思い切って禁止!!と、してしまうのもテですが、それもナニですので、2バイト文字使用可にしましょう。
それには、file_column Plugin をいじります。
file_column Plugin は、/vendor/plugins/trunk にインストールされています。さらに、lib ディレクトリの中を見ると、file_column.rb というファイルがありますので、RadRails でこれを開きます。
すずーっとスクロールしていくと、一番終わりに、
def self.sanitize_filename(filename) filename = File.basename(filename.gsub("\\", "/")) # work-around for IE filename.gsub!(/[^a-zA-Z0-9\.\-\+_]/,"_") filename = "_#{filename}" if filename =~ /^\.+$/ filename = "unnamed" if filename.size == 0 filename end |
ファイル名のサニタイジングをしていますね。filename.gsub!(/[^a-zA-Z0-9\.\-\+_]/,"_")の部分は、ファイル名に含まれる半角英数字以外をアンダーバーに置き換えます。どうやらここで2バイト文字がハネられている様です。
サニタイジングはセキュリティに係わる部分ですが、思い切って書き換えます。
filename.gsub!(/[^\w\.\-\+_]/,"_") |
これで2バイト文字も通して貰えるようになります。メデタシ、メデタシ。
……って、WindowsXP のフォルダに、ファイル名 UTF-8 で書かれちゃうのね。変換ロジック書くのもめんどいし、ま、いっか(ちゃんとしたい人は、勝手に変換して下さい。または、Linux かなんかで、ファイルシステムを UTF-8 にして運用して下さい――って、ダメ?)。
file_column Plugin の弱点は、ドキュメント類の少なさではないか、と勝手に思うわけです。 /vendor/plugins/trunk/lib で、 rdoc と打てばドキュメントが出てきますが、英語だし、もうちょっと何とかして欲しいです。 誰か、インターネット上に豊富なサンプルコード付きでマニュアル公開してくれないかなぁ。もち、日本語で。 |