MiniMagick无法编写解码的Base64图像

时间:2017-12-16 04:47:25

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

我在使用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

我在代码中的前几行添加了注释来描述它们的值。 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来自类似的问题,这就是为什么我以这种方式构建它。

1 个答案:

答案 0 :(得分:0)

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

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