I'm using Carrierwave and carrierwave-base64 for file upload on Amazon S3.
How can I compress uploaded files only if they are over xMB. Files are in jpeg, png and jpg formats as images.
I think you can use before :store hook. For example:
before :store, :compress_file
def compress_file(_file)
file_size = (File.size(file.path).to_f / 2**20)
if file_size > x
# compress file
end
end
Related
I want to compress my images only when the size is greater than 200kb before uploading them to s3 bucket,In my case images are not connected with any model, I am directly uploading it to s3 using storage as aws
My Uploader is
class CoverImageUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
#include CarrierWave::RMagick
include CarrierWave::MiniMagick
process :compress_image, if: :size_is_large?
# Choose what kind of storage to use for this uploader:
storage :aws
# 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 initialize(location_id)
#location_id = location_id
end
def store!(*args)
super
#file
end
def store_dir
"uploads/cover-images/#{#location_id}"
end
def compress_image
manipulate! do |img|
img.quality("60")
img
end
end
def size_is_large? picture
image = MiniMagick::Image.new(picture.path)
(image[:size]/1000) > 200
end
end
I am using following code to upload the image
image = MiniMagick::Image.open(https://abc.s3.amazon.com/uploads/image.png)
image_type = image.type.downcase
image_name = "#{location}.#{image_type}"
image_path = Rails.root.join("tmp", image_name)
file = File.open(image_path, 'wb') do |output|
output.write RestClient.get(cover_image["url"])
output.path
end
uploader = CoverImageUploader.new("test123")
s3_path = File.open(file) do |file|
uploaded_image = uploader.store!(file)
uploaded_image.url
end
For jpg and jpeg the above code is working fine but in case of png image, instead of decreasing the size its increasing the image size
My file size was 602 kb in png but it got increased to 1.3 mb after uploading it to s3
I want it to be compressed so the image can load faster on our webpages.
Can anyone please suggest what should I do for png image to be compressed ?
I am struggling to access files on S3 with Carrierwave.
In my uploader file doc_uploader.rb I have the following code
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
to uplooad "doc" model defined as follow
class Doc < ActiveRecord::Base
belongs_to :user
mount_uploader :doc, DocUploader
end
To access the uploaded file I have the following line of code in a controller
#doc = current_user.docs.order("created_at").last #last file uploaded by user
io = open("#{Rails.root}/public" + #doc.doc.url)
Everything works perfectly locally. Now I want to move my file to S3 in the uploader I use fog and replace
storage :file
by
storage :fog
I adjust my config file carrierwave.rb and uploading works perfectly. However, to access the file I try to use
#doc = current_user.docs.order("created_at").last
io = open("#{#doc.doc.url}")
and I get the following error
No such file or directory # rb_sysopen - /uploads/doc/doc/11/the_uploaded_file.pdf
Could anyone give me the right syntax to access the file on S3 please? Thanks.
When accessing the asset through the console, it gives you only the path, you might need to append the protocol & host to the #doc.doc.url, something like:
io = open("http://example.com#{#doc.doc.url}")
Or you can set the asset url on the environment you need to, but this is not really necessary:
config.asset_host = 'http://example.com'
This only applies if you are using the console, on any web view this will not apply, carrierwave seems to handle it
I am using Carrierwave to upload images and that works fine but I am now trying to use Minimagick to process these uploaded images.
What is going on?
The images still upload as well as their thumb version, however both images are exactly the same size.
Here is the uploader code:
class FileUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# Override the directory where uploaded files will be stored.
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Create different versions of your uploaded files:
version :thumb do
process :resize_to_fit => [100, 100]
end
# Add a white list of extensions which are allowed to be uploaded.
def extension_white_list
%w(jpg jpeg gif png)
end
end
And here is how I am calling it:
<%= image_tag example.my_file.url(:thumb).to_s %>
I dont think it is anything to do with the way I am calling it because the two files created by all this are the same, so sound slike its to do with processing it on upload.
Here is the folder created for each object:
Image
--- Fixed ---
The issue was ImageMagick. It was not properly configured on my machine so that means no gem that deals with image processing (Paperclip, Minimagick or Dragonfly) could complete any image manipulation.
I am trying to generate a csv file in a rake task and...
Email it
Upload it to Amazon s3.
Here is the task.
desc "This task is called by the Heroku scheduler add-on"
require 'csv'
task :send_report => :environment do
file = Baseline.to_csv
ReportMailer.database_report(file).deliver_now
Report.create!(:data => file)
end
The generation of the csv file and attachment to the email works fine (not shown). Its the carrierwave upload that isn't working. Please note that I have other uploaders for other models and they work fine so my bucket settings are correct.
Here are the other files.
class Report < ActiveRecord::Base
mount_uploader :data, ReportUploader
end
and
class ReportUploader < CarrierWave::Uploader::Base
storage :fog
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def extension_white_list
%w(jpg jpeg gif png csv xls)
end
end
I have tried various permutations such as store! with not luck. I should add that if I look at the database, the new report is being created (and the data attribute is "nil", with no upload in sight)
Thanks
I have successfully implemented image uploading using carrierwave, fog and Amazon S3. In my imageuploader am using only fog as storage. But when i check my database i can see that just the file name is written instead of the amazon url. In my views its fetching correctly from aws without any issues.
Is it supposed to be like this?
If so how the application figure out the exact url to s3?
imageuploader.rb`
# encoding: utf-8
class ImageUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
include CarrierWave::MiniMagick
#Include the sprockets-rails helper for Rails 4+ compatibility:
include Sprockets::Rails::Helper
storage :fog
version :index_size do
process :resize_to_fill => [258, 173]
end
version :thumb_size do
process :resize_to_fill => [100, 100]
end
def extension_white_list
%w(jpg jpeg gif png)
end
end
Your config has the bucket name and the database has the filename. These are the only two pieces of information that are actually required to construct a filename (and it can be done without other API calls). The urls are actually pretty regular, so it is fairly straightforward for the server to do this. Hope that helps!