【问题标题】:MiniMagick can't write decoded Base64 imageMiniMagick 无法写入解码后的 Base64 图像
【发布时间】:2017-12-16 04:47:25
【问题描述】:

我在使用 MiniMagick 在 Rails 中解码的 base64 图像上调用 image.write 时遇到问题。除了 image.write 之外,每一行似乎都工作正常。下面的代码在我的 Rails API ImageController 中,我的 React 前端通过带有编码图像的 POST 请求来访问它。

def create
    uploaded_io = params["image_io"]["base64"] # base64 string + metadata
    metadata = uploaded_io.split(',/')[0] + "," # "data:image/jpeg;base64,"
    filetype = metadata.split("/")[1].split("base64")[0][0...-1] # "jpeg"
    base64_string = uploaded_io[metadata.size..-1] # base64 string w/o metadata
    blob = Base64.decode64(base64_string)
    image = MiniMagick::Image.read(blob)
    image.write `#{Time.new.to_i}.#{filetype}` 

    storage = Google::Cloud::Storage.new(
        project_id: ENV['GOOGLE_CLOUD_PROJECT'],
        credentials: JSON.parse(File.read('config/google_cloud_credentials.json'))
    )

    bucket = storage.bucket "auto-stock-189103.appspot.com"
    bucket.create_file image,`test/#{Time.new.to_i}.jpg`
end

我在描述其值的代码的前几行中添加了 cmets。 base64_string 太长无法评论,所以这里是它的值:

"/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABkAAD/4QMtaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTNDQjQyRjlEQTAxMTFFN0E4N0VBNzdGODEwREFGMTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTNDQjQyRkFEQTAxMTFFN0E4N0VBNzdGODEwREFGMTYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoxM0NCNDJGN0RBMDExMUU3QTg3RUE3N0Y4MTBEQUYxNiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoxM0NCNDJGOERBMDExMUU3QTg3RUE3N0Y4MTBEQUYxNiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv/uAA5BZG9iZQBkwAAAAAH/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAgICAgICAgICAgMDAwMDAwMDAwMBAQEBAQEBAgEBAgICAQICAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA//AABEIAAoACgMBEQACEQEDEQH/xABNAAEBAAAAAAAAAAAAAAAAAAAACQEBAQEAAAAAAAAAAAAAAAAAAAkKEAEAAAAAAAAAAAAAAAAAAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCMKU7f4AAA/9k="

测试它here 会呈现正确的图像(红色方块),但是当我运行image.write 行时,它会返回以下错误:

bin/rails: No such file or directory - 1513397345.jpeg
*** NoMethodError Exception: undefined method `write' for nil:NilClass
nil

这里是image = MiniMagick::Image.read(blob)的返回值供参考:

#<MiniMagick::Image:0x00007f9ba76ba1f8 @path="/var/folders/pf/xhvv11092_j08hw47q6rt9z80000gn/T/mini_magick20171215-26353-l2lcyu", @tempfile=#<Tempfile:/var/folders/pf/xhvv11092_j08hw47q6rt9z80000gn/T/mini_magick20171215-26353-l2lcyu (closed)>, @info=#<MiniMagick::Image::Info:0x00007f9ba76ba1d0 @path="/var/folders/pf/xhvv11092_j08hw47q6rt9z80000gn/T/mini_magick20171215-26353-l2lcyu", @info={}>>

最终,我的目标是将图像上传到 Google Cloud,所以如果有更好的方法,请告诉我。我从一个类似的问题中关注this answer,这就是我采用这种结构的原因。

【问题讨论】:

标签: ruby-on-rails ruby base64 imagemagick decode


【解决方案1】:

我认为您的问题是您在使用双引号的地方使用了反引号:

image.write `#{Time.new.to_i}.#{filetype}` 
# ----------^----------------------------^

反引号将尝试在 shell 中执行它们的内容。您没有名为 1513397345.jpeg 的可执行文件(这是 #{Time.new.to_i}.#{filetype} 的计算结果),因此您会收到错误消息。

您只想使用普通的旧双引号来获得您期望的字符串插值:

image.write "#{Time.new.to_i}.#{filetype}"

下面还有几行:

bucket.create_file image, "test/#{Time.new.to_i}.jpg"

此外,您可能希望将该文件名存储在一个变量中,因为不能保证 Time.new.to_i 在两次调用中都相同:

name = "#{Time.new.to_i}.#{filetype}
image.write name
#...
bucket.create_file image, name

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-06
    • 2016-01-13
    • 2012-06-21
    • 1970-01-01
    • 2014-01-19
    相关资源
    最近更新 更多