MiniMagick无法编写解码的Base64图像

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MiniMagick无法编写解码的Base64图像相关的知识,希望对你有一定的参考价值。

我在使用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从一个类似的问题,这就是为什么我这样结构。

答案

我认为你的问题是你在使用反引号,你的意思是使用双引号:

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

以上是关于MiniMagick无法编写解码的Base64图像的主要内容,如果未能解决你的问题,请参考以下文章

在 Powerapps 中使用 .image 属性将 Base64 字符串解码为图像并显示

在python中将base64编码的图像解码为原始图像

无法在模板上呈现 PIL 对象 base64 图像

在Grails中解码base64图像[重复]

在 C# 中将 Base64 字节数组解码为图像

如何使用颤振将 Base64 字符串解码为图像文件