由Ruby on Rails的Base64生成的图像被破坏

时间:2018-02-21 09:27:43

标签: ruby-on-rails file base64

我正在创建一个使用React处理多个上传的表单,所以我有base64字符串,我希望"转换回"到图像。 为了在表单提交之前和之后进行测试,我可以确保base64没有被破坏。

我发现了几个关于如何使用Rails从base64重新创建图像的问题,但是我不得不稍微调整一下,现在生成的图像已经坏了。

以下是我处理它的方式:

def portfolio_params
    params.require(:portfolio).permit(:title, :creation_time,
                                      :public, :content, { illustrations: [] },
                                      :slug, :thumbnail, :website, :tags)
    port_params[:illustrations] = parse_image_data(port_params[:illustrations]) if port_params[:illustrations]
    port_params
  end

def parse_image_data(base64)
    require 'fileutils'
    filename = 'portfolio-file-'
    path = 'public/uploads/portfolio/' + Time.now.strftime('%d%m%Y%H%i%s')

    # Check if directory exists, creates it if not
    FileUtils.mkdir_p(path) unless File.directory?(path)

    # creation of the response variable
    response = []

    # Since I'm getting an array (multiupload), I have to loop through it
    base64.each_with_index do |b, i|

      # Extracts the file format (png, jpg, jpeg..)
      _in_content_type, format, _encoding, _string = b.split(/[:\/;,]/)[1..4]

      # Creates the file with the index so the file doesn't get rewritten
      File.open(path + '/' + filename + i.to_s + '.' + format, 'wb') do |f|

        # Fills it with the decoded base64 string
        f.write(Base64.decode64(b))
      end

      # Response made to the params so that the image path gets saved instead of the base64
      response.push(path + '/' + filename + i.to_s + '.' + format)
    end

  response
end

理论上一切正常:我的数据库保存路径,文件被创建,但......不正确。

我不确定我在做什么,我哪里做错了?

提前谢谢

1 个答案:

答案 0 :(得分:1)

对于那些可能(很可能)遇到同样麻烦的人来说,问题在于" base64"前缀,如下所示:

data:image/gif;base64,

不会被方法Base64.decode64识别,只能识别之后的

所以我更改了以下代码:

base64.each_with_index do |b, i|
  _in_content_type, format, _encoding, _string = b.split(/[:\/;,]/)[1..4]

  File.open(path + '/' + filename + i.to_s + '.' + format, 'wb') do |f|
    f.write(Base64.decode64(b.partition('base64,').last))
  end

  response.push(path + '/' + filename + i.to_s + '.' + format)
end

代码b.partition('base64,')创建一个数组,其中包含在分区参数之后的所有内容。