2011-02-27 4 views
24

これはかなり簡単ですが、私はそれを動作させることはできません。画像をレンダリングする

私は、クエリに基づいて画像を見つけるコントローラメソッドを持っています。そして、出力はキャッシュに入れられます。画像はリモート(フリッカー、グーグル画像など)であったり、ローカルであったりする可能性があります。ソースに関係なく、イメージファイルの内容を取得してユーザーに渡すだけです。本質的には、プロキシです。リモート画像を通すことはうまくいくようですが、ローカル画像を通過すると、私には次のように伝えられます:

invalid byte sequence in UTF-8 

私は誰かが問題を解決したり、私のコードでより良い方向に私を導くことを望んでいます。

def image_proxy 
    query = params[:query] 
    image_url = get_image_url(query) # returns an absolute local file path or a URL 

    response.headers['Cache-Control'] = "public, max-age=#{12.hours.to_i}" 
    response.headers['Content-Type'] = 'image/jpeg' 
    response.headers['Content-Disposition'] = 'inline' 
    render :text => open(image_url).read 
end 

ローカルファイルは正常に動作しません。この他の問題を解決することができます誰にでも

ボーナス:

  1. は、私は適切なコンテンツタイプを設定する必要があります。リモートイメージURLはイメージタイプを教えてくれません。私はただURLを取得し、URLには拡張子が含まれないことがあります。だから私はjpegを選んだので、それは私に送られた画像の種類に関係なく動作するようだ。

ありがとう!

答えて

23

render :text => open(image_url, "rb").readを使用してみてください。これは、Rubyに開くファイルがバイナリであり、テキストとして読み込まないように指示します。ボーナスの質問については

編集

、あなたは最初の数バイトを読み込み、そこに含まれるどのような時に見ることができます。 PNGは、常に16進数のバイト値89 50 4E 47 0D 0A 1A 0A(または10進値137 80 78 71 13 10 26 10)で始まります。

ウィキペディアには、あなたが見ることができるlist of magic numbers used to identify fileがあります。最初の数バイトを読み込んでそれを比較するメソッドを作成するだけです。

+0

偉大な答え、完璧に働いた。 –

14

どのバージョンのRailsですか? Rails 3では、追加されたstreaming methodsを見てください。 send_dataはバイナリデータを送信する適切な方法です。イメージがローカルで、Webサーバーがサポートしている場合は、ユーザーがイメージをダウンロードしている間にrailsインスタンスをブロックしないsend_fileを使用できます。

+1

はい、 'send_data'は' render'ではなく、あなたが望むものです。 – aceofspades

関連する問題