Carrierwave: преобразовать загруженный PNG в JPG, заменив исходную версию (или: имея версии с форматом файла, отличным от исходного файла) - PullRequest
0 голосов
/ 10 марта 2020

У меня есть следующая модель:

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 в a <textarea>, затем загруженный с использованием https://github.com/y9v/carrierwave-base64 gem:

class Finding < ApplicationRecord
  mount_base64_uploader :screenshot, ScreenshotUploader
end

В форме HTML это выглядит так:

upload form

После загрузки получаются следующие файлы:

  • screenshot.png это PNG, а не JPG!
  • thumb_screenshot.jpg
  • print_screenshot.jpg

Но мне нужно, чтобы исходный файл также был преобразован в JPG, так как мне нужно сэкономить место на диске. Как мне этого добиться?

Ответы [ 2 ]

1 голос
/ 28 марта 2020

Добавляя к ответу Василия, я придумал следующее:

  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, и у меня нет никакой мотивации углубляться в это. Таким образом, предлагаемое решение может быть не слишком полезным, но ради документации я хотел бы опубликовать его здесь.

В моем особом случае я решил дать go идею экономии дискового пространства путем преобразования PNG в JPG. Вместо этого я просто установил process quality: 80, чтобы сэкономить хотя бы немного места в версиях.

Для исходного PNG (который сохраняется в без потерь с помощью гема carrierwave-base64), я просто использую следующий код для сжатия его качество:

  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
1 голос
/ 11 марта 2020

Вы можете сделать это так, как написано в документации несущей волны Просто замените system("mogrify -resize '1200\>' #{file.file}") на system("mogrify -format jpg #{file.file}") и затем удалите оригинальный файл.

...