如何将Magick::Image对象直接传递给Carrierwave上传器
免本地临时文件实现 RMagick 图片对象直接传入 Carrierwave 上传器
你可以通过将RMagick图片对象转为内存二进制流,再封装为带必要属性的StringIO对象的方式,完全省去本地临时文件读写步骤,优化后的实现代码如下:
def convert_to_images user_cv_images.destroy_all Magick::ImageList.new(self.file.file.file) do self.quality = 100 self.density = 144 self.colorspace = Magick::RGBColorspace self.interlace = Magick::NoInterlace end.each_with_index do |image, index| image.resize_to_fit!(1600, 10000) # 直接在内存生成PNG格式二进制数据 image_blob = image.to_blob { self.format = 'PNG' } # 封装为内存IO对象,补充Carrierwave要求的属性 io = StringIO.new(image_blob) io.define_singleton_method(:original_filename) { "page-#{index + 1}.png" } io.define_singleton_method(:content_type) { 'image/png' } # 直接传入上传器,无本地文件操作 user_cv_images.create(image: io, position: index + 1) end end
核心逻辑说明
- 调用
Magick::Image#to_blob方法可直接在内存中将图片转换为指定格式的二进制数据,无磁盘IO开销 StringIO是Ruby标准库提供的内存IO类,默认已经实现了Carrierwave要求的read方法,只需额外补充original_filename(用于生成上传后的文件名)和content_type(用于标识文件格式)两个属性即可被Carrierwave正常识别- 该实现完全省略了原方案中写入临时文件、读取临时文件、删除临时文件三个步骤,性能更高,也避免了临时文件残留、目录权限不足等潜在问题
内容的提问来源于stack exchange,提问作者Vedran Mijatović
相关产品推荐
相关产品推荐

