63

Ruby on Rails アプリを usps 配送システムと統合しています。郵便料金の請求を行うと、その郵便料金を支払うことになり、払い戻しはできません。

郵便料金のリクエストは、配送ラベルである base64 文字列を含む xml レスポンスを返します。

ビューで配送ラベルをレンダリングすることはできますが、それを簡単にするために、世代間で配送ラベルに何かが発生した場合に備えて、そのbase64文字列をサーバー上の画像として保存できるようにしたいと考えていますそのため)と郵送のため、新しいものを購入せずに再版される場合があります。

私の最初の考えは次のとおりでした

# Attempt 1
File.open('shipping_label.gif', 'w+') {|f|
    f.puts Base64.decode64(base_64_encoded_data)
}

# Attempt 2
File.open('shipping_label.gif', 'w+') {|f|
    f.puts Base64.decode64(Base64.decode64(base_64_encoded_data))
}

どちらも機能しません。

4

4 に答える 4

104

画像の場合のように、バイナリデータをファイルに書き込む場合、のようなテキスト印刷ツールを使用することはできませんIO#puts

確認する必要があるのは2つあります。

  • LFからCRLFへの拡張を回避するには、バイナリモードで書き込む必要があります。
  • 任意のデータで機能するのではwriteなく、putsを使用する必要がありますが、 (文字通り「文字列を置く」)はテキスト専用です。writeputs

これらを組み合わせると、次のようになります。

File.open('shipping_label.gif', 'wb') do |f|
  f.write(Base64.decode64(base_64_encoded_data))
end
于 2009-07-21T19:00:04.993 に答える
25

他の答えはかなり近いですが、通常、base64 ストリームには PNG データが含まれていると想定しています。これは常に当てはまるとは限らないため、正しいファイル拡張子を確立するために MIME タイプ ライブラリを使用することをお勧めします。

REGEXP = /\Adata:([-\w]+\/[-\w\+\.]+)?;base64,(.*)/m

data_uri_parts = data_url.match(REGEXP) || []
extension = MIME::Types[data_uri_parts[1]].first.preferred_extension
file_name = "myfilename.#{extension}"

File.open(file_name, 'wb') do |file|
    file.write(Base64.decode64(data_uri_parts[2]))
end
于 2016-02-20T00:55:21.643 に答える
1

画像に書き込む必要がある場合は、rmagick gem を介して imagemagick を使用します。

http://rmagick.rubyforge.org/

于 2009-07-21T19:41:55.483 に答える