There was a problem that the image list did not line up beautifully because the images uploaded by the user were different in portrait and landscape.
To solve that problem, we added a function to mask the image to a square by giving the image a CSS class name dedicated to portrait and landscape.
I will describe the implementation procedure.
--Development environment uses Docker --Ruby: Uses 2.6.3 Docker image
First, when uploading an image, we will make it possible to resize the image to three sizes with the "Carrier Wave" gem. To be able to resize, do the following:
--Install "Imagemagick" --Install the "Mini Magick" gem --Set the resizing in the "Carrier Wave" gem configuration file
In order to resize with "Carrier Wave", you need to install "MiniMagick" gem. In order to be able to use the "MiniMagick" gem, it is necessary to install software called "Imagemagick". Do the above work.
As you can see in the code quote below, in the "Carrier Wave" uploader config file, By uncommenting the code that includes the "MiniMagick" gem file You will be able to resize the image.
class MyUploader < CarrierWave::Uploader::Base include CarrierWave::MiniMagick #<=You can resize by removing the commented out "MiniMagick" gem. process resize_to_fit: [800, 800] version :thumb do process resize_to_fill: [200,200] end end
To resize the image in the "MiniMagick" gem file, as in the quote below It is necessary to install "Imagemagick".
Note: You must have Imagemagick installed to do image resizing. https://github.com/carrierwaveuploader/carrierwave
Since I am using Docker for the development environment, I added the installation command to the Dockerfile of the ruby image as shown below.
docker/rails/Dockerfile
FROM ruby:2.6.3
#abridgement
RUN apt-get update && apt-get install -y --no-install-recommends\
nodejs \
default-mysql-client \
vim \
yarn \
imagemagick \ #<=add to
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
#abridgement
Gemfile
gem "mini_magick"
$ bunndle install
My uploader name is image, so edit the `` `image_uploader.rb``` file as follows.
app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick #<=Uncomment
#abridgement
# Create different versions of your uploaded files:
version :thumb do
process resize_to_fit: [1024, 1024]
end
version :medium_thumb, from_version: :thumb do
process resize_to_fit: [512, 512]
end
version :small_thumb, from_version: :medium_thumb do
process resize_to_fit: [128, 128]
end
#abridgement
end
When I restarted the Rails app, the image was resized when I uploaded the image.
There were various ways to resize, but the above used a process called "resize_to_fit" that resizes the image at the same aspect ratio. Other resizing methods are explained in GitHu's MiniMagick repository, so please refer to that.
This time, I wanted to display the image as a square in various places, so by inputting the image acquisition as `medium_thumb```,
`small_thumb```, etc. in the method argument, Make it possible to acquire and separate images
The HTML output part has been made into parts to give it versatility.
Therefore, the following work was done.
--By inputting the image acquisition as `medium_thumb```,
`small_thumb```, etc. in the method argument, the image can be acquired and separated.
--Create a partized html.erb file
`medium_thumb```,
`small_thumb```, etc. in the method argument, the image can be acquired and separated.Use the function of the callback function and write the code so that you can get the image with the argument. Since there are users who have already deployed and used the app, when the resized image does not exist, the original image is output.
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protected
# Call the method to get the uploaded image
def get_uploaded_image(image, method = "thumb")
self.send(method.to_sym, image)
end
helper_method :get_uploaded_image
# Returns the value of the src attribute of
# the img tag of the thumbnail size image.
def thumb(image)
unless image.thumb.blank?
return image.thumb.url.to_s
end
image.url.to_s
end
# Returns the value of the src attribute of
# the img tag for a medium-sized thumbnail image.
def medium_thumb(image)
unless image.thumb.blank?
return image.medium_thumb.url.to_s
end
image.url.to_s
end
# Returns the value of the src attribute
# of the img tag for a small-sized thumbnail image.
def small_thumb(image)
unless image.thumb.blank?
return image.small_thumb.url.to_s
end
image.url.to_s
end
end
In the file below, determine whether it is portrait or landscape with the "MiniMagick" method, and give the class name. Reference: MiniMagick's GitHub repository
html.erb:app/views/layouts/_img-square.html.erb
<%
unless image.blank?
image_url = get_uploaded_image(image, version)
image_obj = MiniMagick::Image.open("#{Rails.root.to_s}/public#{image_url}")
class_name = image_obj.width >= image_obj.height ? "img-square__width":"img-square__height"
img_width = image_obj.width
img_height = image_obj.height
else
image_url = "nophoto.jpg "
class_name = "img-square__width"
img_width = 600
img_height = 600
end
%>
<div class="img-square"><%= image_tag image_url, class: class_name, width: img_width, height: img_height %></div>
If the image to be acquired does not exist, I try to acquire the nophoto image.
To call an image using the above parts, call the image as follows.
html.erb
<%= render partial: 'layouts/img-square', locals: { image: current_user.image, version: "small_thumb" } %>
Finally, write the SCSS code so that the image is masked according to the vertical and horizontal class names in the SCSS file.
app/assets/stylesheets/application.scss
.img-square {
width: 100%;
padding-top: 50%;
padding-bottom: 50%;
position: relative;
@at-root {
#{&}__height {
width: 100%;
height: auto;
position: absolute;
top: -50%;
bottom: -50%;
right: -100%;
left: -100%;
margin: auto;
}
#{&}__width {
height: 100%;
width: auto;
max-width: none;
position: absolute;
top: -100%;
bottom: -100%;
right: -100%;
left: -100%;
margin: auto;
}
}
}
--In the future, if you add methods to application_controller.rb
, it is expected that the code will increase and become chaos, so it is necessary to be able to organize the code. so. .. ..
--It would be even better if the original image could be deleted? Since the original image may have a large capacity, it is expected that the server capacity will be squeezed.
There are some things I don't understand, but I'm glad that I managed to implement the article list in a square. I wondered if the image size could be obtained with a Ruby-only method, but I didn't actually check it, so I'm glad I had the "MiniMagick" gem.
Recommended Posts