web-dev-qa-db-ja.com

rubyを使用して、base64文字列を画像として保存する方法

私は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))
}

どちらも動作しません。

47
Ricky

イメージの場合など、バイナリデータをファイルに書き込む場合、IO#putsの使用は危険であり、回避するのが最善です。バイナリモードで記述する必要があります。これは、UNIXやOS XなどのLF専用プラットフォームではほとんど関係ありませんが、WindowsなどのCRLFプラットフォームでは必須です。 IO#putsは、ファイルの最後に無効な改行を追加します。

最善のアプローチは、オープンコールで正しいフラグを指定することです。

File.open('shipping_label.gif', 'wb') do |f|
  f.write(Base64.decode64(base_64_encoded_data))
end

たとえば、IO#openドキュメントページのコメントを参照してください。

http://apidock.com/Ruby/IO/open/class

88
tadman

他の回答はかなり近いものですが、通常、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
19
Piotr Kuczynski
require 'RMagick'
data = params[:image_text]# code like this  data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABPUAAAI9CAYAAABSTE0XAAAgAElEQVR4Xuy9SXPjytKm6ZwnUbNyHs7Jc7/VV9bW1WXWi9q
image_data = Base64.decode64(data['data:image/png;base64,'.length .. -1])
new_file=File.new("somefilename.png", 'wb')
new_file.write(image_data)

画像をファイルとして使用した後、Photo.new(image:image)#save useng Paperclip in Photo model

6
stopanko

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

http://rmagick.rubyforge.org/

1
Corban Brook