I'm trying to upload a PNG and save a bunch of thumbnails. The thumbnails should all be JPG and not have any transparency. Somehow the file is saved as jpg but it has transparency...
Here's my Uploader:
# encoding: utf-8
class WinePhotoUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"assets/wines/#{version_name}"
end
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
# Provide a default URL as a default if there hasn't been a file uploaded:
def default_url
# For Rails 3.1+ asset pipeline compatibility:
ActionController::Base.helpers.asset_path("pages/wines/#{version_name}/default.png")
end
process :for_all
process :convert => 'jpg'
version :croppable, :if => :new_upload? do
process :resize_and_pad => [1200, 1200, 'white']
end
version :show, :if => :new_upload? do
process :resize_to_fit => [nil, '425']
end
version :general, :from_version => :show, :if => :new_upload? do
process :resize_and_pad => [150, 375, 'white']
end
version :thumb, :from_version => :croppable, :if => :cropping? do
process :rotate_to => [-30]
process :crop_via_model
process :resize_to_fit => [150, 150]
end
def for_all
manipulate! do |img|
img.trim
img.gravity = Magick::CenterGravity
# I only use these two because this shit isn't working...these don't seem to help!
# Neither does the flatten method...even though other posts on stackoverflow.com say
# that it works.
img.background_color = 'white'
img.alpha Magick::OpaqueAlphaChannel
img.unsharp_mask 0.3, 0.3, 5, 0
img
end
end
def extend_to(w, h)
manipulate! do |img|
img.gravity = Magick::CenterGravity
img.extent w, h
img
end
end
def rotate_to(deg)
manipulate! do |img|
img.gravity = Magick::CenterGravity
img.distort Magick::ScaleRotateTranslateDistortion, deg
#img.repage # WTF?!?!?!? No repage method?!
img
end
end
def crop_via_model
manipulate! do |img|
img.gravity = Magick::CenterGravity
img.crop model.crop_x.to_i, model.crop_y.to_i, model.crop_w.to_i, model.crop_h.to_i
img
end
end
def flatten
manipulate! do |img|
img_list = Magick::ImageList.new
img_list.from_blob img.to_blob
img_list.new_image(img_list.first.columns, img_list.first.rows) { self.background_color = "white" } # Create new "layer" with white background and size of original image
img = img_list.reverse.flatten_images
img
end
end
def new_upload? picture
!model.cropping?
end
def cropping? picture
model.cropping?
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg gif png tif)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename
"#{ model.get_permalink(:normalized => true) }.jpg"
end
# Remove this when https://github.com/carrierwaveuploader/carrierwave/issues/1164 is solved.
def recreate_versions!(*versions)
if versions.any?
from_versions = versions.group_by { |v| self.class.versions[v][:options][:from_version] }
from_versions.each do |from, versions|
next if from.nil?
file = CarrierWave::SanitizedFile.new(self.versions[from.to_sym].file)
store_versions!(file, versions)
end
else
super(*versions)
end
end
end
Oh...and apparently carrierwave doesn't seem to want to log anything so I can't tell what it's doing.
There appears to be a quirk with imagemagick and order of operations when converting file types.
Full github issue can be found here: https://github.com/carrierwaveuploader/carrierwave/issues/133#issuecomment-615254
Basically
manipulate
is called once for everyprocess
you have.manipulate
opens the current file path, makes changes then writes. Because of this it seems that anyprocess
lines that are called after the format conversion are performed on the original file, not the newly converted one.In order to fix this, you either have to do all of your
process
operations within a singlemanipulate
block or make sure that the conversion is the lastprocess
to run.The example of this from the github issue is: