I am trying to get the dimensions of a image using carrierwave but I was hoping to get the dimensions with my own code I created trying to run fastimage after_save
or after commit
. I get this error:
wrong number of arguments (1 for 0)
Extracted source (around line #45):
# [String] contents of the file
#
def read
file.read if file.respond_to?(:read)
end
carrierwave (0.11.2) lib/carrierwave/uploader/proxy.rb:45:in `read'
fastimage (2.1.0) lib/fastimage.rb:343:in `block in fetch_using_read'
model would look something like this
class Micropost < ApplicationRecord
after_save :change_picture_dimensions
mount_uploader :picture, PictureUploader
def change_picture_dimensions
if :picture?
widthheight = FastImage.size(picture)
if widthheight[0] >= 501
newheightratio = widthheight[1].to_f / widthheight[0].to_f
newheight = newheightratio * 500
self.picture = "<img src=\"" + picture.to_s + "\" width=\"500\" height=\"" + newheight.to_s + "\">"
else
self.picture = "<img src=\"" + picture.to_s + "\" width=\"" + widthheight[0].to_s + "\" height=\"" + widthheight[1].to_s + "\">"
end
end
end
This is just a local file on my system. I can get dimensions using minimagick here but wanted to know more about the process of carrierwave and why I cannot use my method to get the dimensions cause of this error? In my method I am just using a ratio to keep the aspect ratio but fit into the fixed width of a div I have for any image.
EDIT: I realised I need to do it before the object is saved but even with before_create I get the same error.
You cannot assign picture a string. It must be an URL, file or an IO object.
If you want to preprocess your image width to fit 500px just declare the following:
# app/uploaders/picture_uploader.rb
class PictureUploader < CarrierWave::Uploader::Base
...
process resize_to_fit: [500, nil]
end
class Micropost < ApplicationRecord
mount_uploader :picture, PictureUploader
end
To save an image from another server you can do:
micropost = Micropost.create(
picture: 'http://server.example.org/image.png'
)
and now you can render it on the page
= image_tag micropost.picture.url
You can also store image size in your model. Read this documentation how to do this. After you saved your image dimensions into a picture model, you can specify them in image_tag
, but it will be redundant I think because browser will detect image size automatically
= image_tag micropost.picture.url, width: picture.width, height: picture.height