我指的是Shrine cropping image sample和 Shrine wiki cropping image
我感谢有很多人帮助我,
我确实以某种方式实现了显示图像预览,
但是,我不能使用cropbox功能,
我遇到一个错误
actionController::RoutingError (No route matches [GET] "/uploads/cache/1c88e44d2db395bf557c00b5aabb1af0.jpg"):
我想这应该归功于derivation_endpoint插件
我读了Derivation Endpoint,但我不太了解,因此如果您知道如何使用推导功能
端点以及如何解决此问题,您想帮我吗?
shrine.rb:
require "shrine"
require "shrine/storage/file_system"
Shrine.storages = {
cache: Shrine::Storage::FileSystem.new("app/assets/images",prefix:
"uploads/cache"),# temporary
store: Shrine::Storage::FileSystem.new("app/assets/images",prefix:
"uploads"),# permanent
}
Shrine.plugin :pretty_location
Shrine.plugin :determine_mime_type,analyzer: :marcel
Shrine.plugin :activerecord # loads active Record integration
Shrine.plugin :cached_attachment_data # for retaining the cached file across
form redisplays
Shrine.plugin :restore_cached_data # re-extract metadata when attaching a
cached file
Shrine.plugin :validation_helpers
Shrine.plugin :default_url
Shrine.plugin :derivatives
Shrine.plugin :derivation_endpoint,secret_key: "secret"
Shrine.plugin :upload_endpoint,url: true
Shrine.plugin :backgrounding
Shrine::Attacher.promote_block do
PromoteJob.perform_async(self.class.name,record.class.name,record.id,name,file_data)
end
Shrine::Attacher.destroy_block do
DestroyJob.perform_async(self.class.name,data)
end
ImageUploader:
require "vips"
require "image_processing/vips"
class ImageUploader < Shrine
ALLOWED_TYPES = %w[image/jpeg image/png image/webp]
MAX_SIZE = 10*1024*1024 # 10 MB
MAX_DIMENSIONS = [5000,5000] # 5000x5000
plugin :derivatives
Shrine.plugin :backgrounding
Shrine::Attacher.promote_block { PromoteJob.perform_later(record,file_data) }
Shrine::Attacher.destroy_block { DestroyJob.perform_later(data) }
Shrine.plugin :default_url
Shrine.plugin :upload_endpoint,url: true
THUMBNAILS = {
large: [800,800],medium: [600,600],small: [300,300],}
Attacher.derivatives do |original|
vips = ImageProcessing::Vips.source(original)
vips = vips.crop(*file.crop_points) # apply cropping
THUMBNAILS.transform_values do |(width,height)|
vips.resize_to_limit!(width,height)
end
end
plugin :derivation_endpoint,prefix: "derivations/image"
# Default URLs of missing derivatives to on-the-fly processing.
Attacher.default_url do |derivative: nil,**|
next unless derivative && file
file.derivation_url :transform,shrine_class.urlsafe_serialize(
crop: file.crop_points,resize_to_limit: THUMBNAILS.fetch(derivative),)
end
# Generic derivation that applies a given sequence of transformations.
derivation :transform do |file,transformations|
transformations = shrine_class.urlsafe_deserialize(transformations)
vips = ImageProcessing::Vips.source(file)
vips.apply!(transformations)
end
class UploadedFile
# convenience method for fetching crop points from metadata
def crop_points
metadata.fetch("crop").fetch_values("x","y","width","height")
end
end
end
routes.rb:
Rails.application.routes.draw do
mount ImageUploader.derivation_endpoint => "/derivations/image"
mount ImageUploader.upload_endpoint(:cache) => "app/assets/images"
get 'sessions/new'
devise_for :users
resources :users do
resources :blogs
end
# For details on the DSL available within this file,see
https://guides.rubyonrails.org/routing.html
end
fileUproad.js:
import 'uppy/dist/uppy.min.css'
import cropbox from 'cropbox'
import {
Core,FileInput,Informer,ProgressBar,ThumbnailGenerator,Dashboard,XHrupload,AwsS3,AwsS3Multipart,} from 'uppy'
uppy.on('upload-success',(file,response) => {
// retrieve uploaded file data
const uploadedFileData = response.body['data']
// set hidden field value to the uploaded file data so that it's submitted
// with the form as the attachment
hiddenInput.value = JSON.stringify(uploadedFileData)
cropbox(imagePreview,response.uploadURL,{
onCrop(detail) {
let fileData = JSON.parse(hiddenInput.value)
fileData['metadata']['crop'] = detail
hiddenInput.value = JSON.stringify(fileData)
}
})
})
cropbox.js:
import 'cropperjs/dist/cropper.css';
import Cropper from 'cropperjs'
function cropbox(image,url,{ onCrop }) {
image.src = url
new Cropper(image,{
aspectRatio: 1,viewMode: 1,guides: false,autoCropArea: 1.0,background: false,zoomable: false,crop: event => onCrop(event.detail)
})
}
export default cropbox
form.html.erb:
<div class ="row">
<%= form_with model: @blog_form,url: user_blogs_path,local: true do |f| %>
<div class ="field ">
<%= f.label :title,class: "col-sm-12 col-10" %><br />
<%= f.text_field :title,class: "col-sm-12 col-10"%><br />
</div>
<div class ="field">
<%= f.label :content %><br />
<%= f.rich_text_area :content %><br />
<%= @blog_form.get_blog.content %>
</div>
<div class="form-group">
<%= f.fields_for :photos,@blog_form.get_photos do | photos_fields| %>
<%= photos_fields.label :image %>
<%= photos_fields.hidden_field :image,value: photos_fields.object.cached_image_data,class:
"upload-data" %>
<%= photos_fields.file_field :image,accept: ImageUploader::ALLOWED_TYPES.join(","),data: {
upload_server: "upload_server",preview_element: "preview-photo",upload_result_element: "preview-photo-upload-result",}%>
<div class="image-preview">
<!-- static link to the thumbnail generated on attachment -->
<%= image_tag photos_fields.object.image_url(:medium),width: 300,class: "img-thumbnail file-upload-preview",id: "preview-photo" %>
</div>
<% end %>
</div>
<div class="field">
<% f.label :user_id %>
<% f.hidden_field :user_id,value: current_user.id %>
</div>
<%= f.submit "create",class: "btn btn-primary" %>
<% end %>
</div>