【问题标题】:Carrierwave: convert an uploaded PNG to JPG by replacing the original version (or: having versions with a different file format than original file)Carrierwave:通过替换原始版本(或:具有与原始文件不同的文件格式的版本)将上传的 PNG 转换为 JPG
【发布时间】:2020-06-22 15:54:39
【问题描述】:

我有以下型号:

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粘贴剪贴板中的图片并以base64编码字符串保存到&lt;textarea&gt;,然后使用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,因为我需要节省磁盘空间。我怎样才能做到这一点?

【问题讨论】:

    标签: ruby-on-rails png jpeg carrierwave


    【解决方案1】:

    您可以像写在carrier wave documentation 上那样做 只需将system("mogrify -resize '1200\&gt;' #{file.file}") 替换为system("mogrify -format jpg #{file.file}"),然后删除原始文件即可。

    【讨论】:

    • 谢谢,我试试看。我希望它也会相应地更新数据库中的文件名。
    • 虽然这会创建所需的 JPG 文件,但数据库中的文件名仍为“.png”。如何告诉carrierwave相应地更新文件列?
    • 文件名可以自己定义 "#{file&.filename&.split('.')&.first}.jpg" github.com/carrierwaveuploader/carrierwave/wiki/…
    • 我对这些选项进行了很多尝试,但我找不到可行的解决方案(甚至不是一个肮脏的解决方案)。不过还是谢谢你。
    【解决方案2】:

    除了 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 有关的一些怪癖,我没有任何进一步深入研究的动力。所以建议的解决方案可能不太有用,但为了文档,我想在这里发布。

    在我的特殊情况下,我决定放弃通过将 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-22
      • 2018-02-28
      • 2018-07-22
      • 1970-01-01
      • 1970-01-01
      • 2014-02-24
      • 2012-01-27
      相关资源
      最近更新 更多