ググってもあんまり出てこなかったのでメモを残しておきます。
JSは Cropper.js を利用しています。ライセンスはMITです。
こんな感じ
やり方
cropper.jsを使って画像を表示し、保存ボタン押下時に切り抜くための情報をRailsに送ります。 Rails側では保存前に切り抜き処理を行い、保存するだけ。
view
ライブラリ
yarn add で cropperjs を入れます。
file inputを用意します
Stimulusでmodalを表示する設定も入れておきます。
# show.html.haml .uploading-images.pt-3 = form_with url: user_images_path(@user), local: true, data: { controller: "preview" } do |f| .input-group = f.file_field :images, class: "form-control override-bs-file image-selection", "data-action": "input->preview#show"
modalで表示
ポイントはhidden_fieldに cropper.js で取得できる切り抜くための値をセットします。
他にもrotateやscaleも取れます。
#preview-modal.modal{"aria-hidden" => "true", tabindex: "-1", "data-preview-target": "modal"} .modal-dialog .modal-content .modal-header %button.btn-close{"aria-label": "Close", "data-bs-dismiss": "modal", type: "button"} .modal-body .modal-preview-content{ "data-preview-target": "content" } .modal-footer = f.submit "保存", class: "btn btn-outline-dark small modal-submit" = f.hidden_field :image_x = f.hidden_field :image_y = f.hidden_field :image_w = f.hidden_field :image_h
stimlus
modal表示する際に、input fileから画像を読み取りcropper.jsに渡します。
# app/javascript/controllers/preview_controller.js import { Controller } from "@hotwired/stimulus" import * as bootstrap from "bootstrap" import Cropper from "cropperjs" export default class extends Controller { static targets = ["content", "modal"] static bsModal initialize() { this.bsModal = new bootstrap.Modal(this.modalTarget) } show(e) { if (e.target.value !== "") { this.bsModal.show() const file = e.target.files[0] const blob = window.URL.createObjectURL(file) const img = document.createElement("img") img.setAttribute("src", blob) img.classList.add("preview-img") this.contentTarget.innerHTML = '' this.contentTarget.appendChild(img) new Cropper(img, { scalable: false, rotatable: false, zoomable: false, crop(event) { document.getElementById("image_x").value = event.detail.x; document.getElementById("image_y").value = event.detail.y; document.getElementById("image_w").value = event.detail.width; document.getElementById("image_h").value = event.detail.height; } }) } } }
Rails
ライブラリ
画像編集のために、image_processing をインストールします。
かつてはImageMagickが利用されていましたが、今はlibvipsがデフォルトで利用されるとのとこ。
macはbrew install vips でインストールできます。
gem "image_processing", ">= 1.2"
Rails Controller
crop を使います。
crop!
で切り抜きが実行されます。
def create user = User.find(params[:user_id]) uploaded_image = params[:images] cropped_image = ImageProcessing::Vips .source(uploaded_image.tempfile.path) .crop!(params[:image_x].to_f, params[:image_y].to_f, params[:image_w].to_f, params[:image_h].to_f) uploaded_image.tempfile = cropped_image user.images.attach(uploaded_image) redirect_to user_path(user), notice: "画像を登録しました。" end
参考
・Rails,Cropper,CarrierWave,MiniMagickで画像を任意の位置でトリミングして登録するまで - Qiita