Carrierwave:通过替换原始版本(或:具有与原始文件不同的文件格式的版本)将上传的 PNG 转换为 JPG
Carrierwave: convert an uploaded PNG to JPG by replacing the original version (or: having versions with a different file format than original file)
我有以下型号:
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.com/layerssss/paste.js and is saved as a base64 encoded string into a <textarea>
, then uploaded using the https://github.com/y9v/carrierwave-base64 gem:
从剪贴板粘贴图像来上传图像
class Finding < ApplicationRecord
mount_base64_uploader :screenshot, ScreenshotUploader
end
在HTML形式中,它看起来像这样:
上传后得到如下文件:
screenshot.png
这是 PNG,不是 JPG!
thumb_screenshot.jpg
print_screenshot.jpg
但我需要将原始文件也转换为JPG,因为我需要保存磁盘space。我怎样才能做到这一点?
你可以像carrier wave documentation上写的那样做
只需将 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
,因此所有图像都被删除。
我认为这是与 carrierwave-base64 gem 有关的一些怪癖,我没有任何进一步深入研究的动力。所以建议的解决方案可能不太有用,但为了文档,我想 post 在这里。
在我的特殊情况下,我决定放弃通过将 PNG 转换为 JPG 来节省磁盘空间的想法 space。相反,我只是设置 process quality: 80
以在版本上至少保存一些 space。
对于原始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
我有以下型号:
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.com/layerssss/paste.js and is saved as a base64 encoded string into a <textarea>
, then uploaded using the https://github.com/y9v/carrierwave-base64 gem:
class Finding < ApplicationRecord
mount_base64_uploader :screenshot, ScreenshotUploader
end
在HTML形式中,它看起来像这样:
上传后得到如下文件:
screenshot.png
这是 PNG,不是 JPG!thumb_screenshot.jpg
print_screenshot.jpg
但我需要将原始文件也转换为JPG,因为我需要保存磁盘space。我怎样才能做到这一点?
你可以像carrier wave documentation上写的那样做
只需将 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
,因此所有图像都被删除。
我认为这是与 carrierwave-base64 gem 有关的一些怪癖,我没有任何进一步深入研究的动力。所以建议的解决方案可能不太有用,但为了文档,我想 post 在这里。
在我的特殊情况下,我决定放弃通过将 PNG 转换为 JPG 来节省磁盘空间的想法 space。相反,我只是设置 process quality: 80
以在版本上至少保存一些 space。
对于原始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