0

Love carrierwave.

When running the recreate_version! the quality of ORIGINAL image is dramatically reduced/corrupted.

I need to use carrierwave's recreate_version! to add a new "mobile" version to an existing Photo model via the mount_uploader :image.

Existing version: original, :card and :thumb

Again, when running the recreate_version! the quality of ORIGINAL image is dramatically reduced.

Mayor image corruption of the original to the point the image should be discarded and re-uploaded.

The :mobile version which is created new from the original is of excellent quality.

And the :card and :thumb versions remain the same, no difference.

Just the original is corrupted. Weird.

As a test, I re-ran the 'photo.image.recreate_versions!(:mobile)' several times to test different parameters trying to catch the corruption culprit (removed un-need gems, recreate :thumb version, etc.). But each time the quality of the original image got worst and worst.

And the higher the dpi the quicker the corruption: 300dpi first pass super ugly, 100dpi two passes yuck, and 72dpi after three passes is just criminal.

Corruption happens on localhost, as well as, Heroku (both staging and production).

Weird. I have used Carrierwave for years and this is the first time with such a problem.

ruby '2.4.1'

rails '5.1.7'

gem 'carrierwave', :git => 'https://github.com/carrierwaveuploader/carrierwave.git'

Here is the setup.

I pass the call to carrierwave recreate_version through Delayed_Job one user at a time

<% @user.photos.find_each do |photo| %>
  <% photo.delay.recreate_mobile %> 
<% end %>

and in the Photo model

class Photo < ApplicationRecord
    def recreate_mobile
      self.image.recreate_versions!(:mobile) if self.image?
    end
end

and in the ImageUploader

class ImageUploader < CarrierWave::Uploader::Base

 include ::CarrierWave::Backgrounder::Delay
 include CarrierWave::MiniMagick
 include CarrierWave::BombShelter
 include CarrierWave::Processing::MiniMagick

  storage :aws

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  process resize_to_limit: [1350, 1350]

  process :store_dimensions

    version :mobile do
        process resize_to_limit: [400, 600]
    end

    version :card do
        process resize_to_limit: [300, 460]
    end

    version :thumb, from_version: :card do
        process resize_to_limit: [100, 150]
    end

  private

  def store_dimensions
    if file && model
      model.width, model.height = ::MiniMagick::Image.open(file.file)[:dimensions]
    end
  end

  def max_pixel_dimensions
    [6024, 6024]
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end

end

and the gems

gem 'carrierwave-aws'
gem 'carrierwave', :git => 'https://github.com/carrierwaveuploader/carrierwave.git'
gem 'carrierwave_backgrounder'
gem 'carrierwave-bombshelter'
gem 'carrierwave-processing'
gem 'mini_magick'
gem 'remotipart', '~> 1.2'

Removed ALL of the unnecessary gems. Still a image corruption issue.

Quality of the original image and all versions are excellent.

It is just after running recreate_version the original image is corrupted.

Any ideas on how to prevent the original image quality from corrupting after recreate_version?

Mark
  • 434
  • 5
  • 6

1 Answers1

0

Solved it: switch processing to RMagick

Within the carriewave image_uploader.rb file

replace:

include CarrierWave::MiniMagick

include CarrierWave::Processing::MiniMagick

with:

include CarrierWave::RMagick

include CarrierWave::Processing::RMagick

MiniMagick is considered to have better memory management, but is rather outdated. Plus is corrupted the images. Fingers crossed RMagick has better memory management by now.

RMagick for the win!

Mark
  • 434
  • 5
  • 6