Ruby on rails 如何使用ruby将base64字符串保存为图像
我正在将我的Ruby on Rails应用程序与usps配送系统集成。一旦你提出邮资要求,你就要支付邮资,邮资是不可退还的 邮资请求将返回一个包含base64字符串的xml响应,该字符串是发货标签 我能够在视图中呈现装运标签,但是为了使其万无一失,我希望能够将base64字符串保存为服务器上的图像,以防在生成(付费)和邮寄之间装运标签发生问题,因此可以在不购买新标签的情况下重新打印 我最初的想法如下Ruby on rails 如何使用ruby将base64字符串保存为图像,ruby-on-rails,ruby,image,file-io,base64,Ruby On Rails,Ruby,Image,File Io,Base64,我正在将我的Ruby on Rails应用程序与usps配送系统集成。一旦你提出邮资要求,你就要支付邮资,邮资是不可退还的 邮资请求将返回一个包含base64字符串的xml响应,该字符串是发货标签 我能够在视图中呈现装运标签,但是为了使其万无一失,我希望能够将base64字符串保存为服务器上的图像,以防在生成(付费)和邮寄之间装运标签发生问题,因此可以在不购买新标签的情况下重新打印 我最初的想法如下 # Attempt 1 File.open('shipping_label.gif', 'w+'
# 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))
}
两者都不起作用 在将二进制数据写入文件(例如图像)时,不能使用诸如
IO\puts
之类的文本打印工具
您需要确保两件事:
- 您需要以二进制模式写入,以避免任何可能的LF到CRLF扩展
- 您必须使用
而不是write
,因为put
可以处理任意数据,但write
(字面意思是“put string”)仅用于文本put
File.open('shipping_label.gif', 'wb') do |f|
f.write(Base64.decode64(base_64_encoded_data))
end
如果需要将其写入图像,请通过rmagick gem使用imagemagick 之后可以将图像用作文件
Photo.new(image:image)#在照片模型中使用回形针保存其他答案非常接近,但通常假设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
这件工作做得很好。谢谢你的解释和链接。@AhmedSalah不知道你的意思。这对base64编码数据仍然有效。@tadman我正试图保存PNG图像,但图像文件已损坏,例如图像查看器说“读取PNG图像文件时出现致命错误:不是PNG文件”,我也有类似的Q here REGEXP=/\Adata:([-\w]+\/[-\w\+\.]+)?;base64,(.*)/m语法错误异常:(byebug):1:未终止的regexp遇到文件结尾…=/\Adata:([-\w]+\/[-\w\+\.]+)?为什么需要“RMagick”?解决方案的其余部分不使用它
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