我有以下模型。
class ScreenshotUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
convert :jpg
version :thumb do
process resize_to_fill: [50, 50]
end
def extension_whitelist
%w(jpg jpeg gif png)
end
version :print do
process border: ['black']
process quality: 80
end
end
通过粘贴剪贴板上的图片上传图片,通过 https:/github.comlayersspaste.js。 并以base64编码字符串的形式保存到一个 <textarea>
,然后使用 https:/github.comy9vcarrierwave-base64。 gem。
class Finding < ApplicationRecord
mount_base64_uploader :screenshot, ScreenshotUploader
end
在HTML表格中,它看起来像这样。
上传后,结果是以下文件:
screenshot.png
是PNG,不是JPG!thumb_screenshot.jpg
print_screenshot.jpg
但我需要将原文件也转换为JPG,因为我需要节省磁盘空间。我怎样才能实现这个目标呢?
你可以像写在 载波文件替换成 system("mogrify -resize '1200\>' #{file.file}")
与 system("mogrify -format jpg #{file.file}")
然后删除原文件。
在Vasiliy的回答基础上,我想到了下面的办法。
after :store, :convert_original_to_jpg
def convert_original_to_jpg(new_file)
if version_name.nil?
system("mogrify -format jpg -quality 80 #{file.file}")
system("unlink #{file.file}") # Remove the old PNG file
model.update_column mounted_as, "#{mounted_as}.jpg" # The filename in the DB also needs to be manually set to .jpg!
end
end
虽然这个方法在创建文件时有效,但在更新文件时却无效,因为... ... new_file
参数则为 nil
因此,所有的图片都被删除了。
我想这是与base64 gem有关的一些怪癖,我没有任何动力去进一步研究这个问题。所以提出的解决方案可能不太有用,但为了记录,我想把它贴在这里。
在我的特殊情况下,我决定放弃通过将PNG转换为JPG来节省磁盘空间的想法。相反,我只是简单地设置了 process quality: 80
以节省至少一些版本上的空间。
对于原始的PNG(它是由carrierwave-base64 gem以无损状态保存的),我只需使用下面的代码来缩小其质量。
after :store, :optimise_images
def optimise_images(new_file)
return if Rails.env.test? # Optimising consumes quite some time, so let's disable it for tests
if version_name.nil?
image_optim = ImageOptim.new pngout: false,
svgo: false,
pngcrush: false,
optipng: false,
pngquant: {allow_lossy: true}, # Everything disabled except pngquant, to keep the performance at a good level
advpng: false
image_optim.optimize_images!(Dir["#{File.dirname(file.file)}/*.png"])
end
end