如何使用cropper.js 对图像应用裁剪?
Posted
技术标签:
【中文标题】如何使用cropper.js 对图像应用裁剪?【英文标题】:How to apply cropping to image with cropper.js? 【发布时间】:2020-09-09 04:48:46 【问题描述】:我正在努力实现,如何使用cropper.js,到目前为止它看起来还不错,但是......当我尝试裁剪图像时,如何将结果放回我的表单?
我的输入有 id 'profile_avatar'。所以我尝试将更新的图像放在那里,但不能。
$('#cut_button').click(function(e)
e.preventDefault();
var croppedImageDataURL = cropper.getCroppedCanvas()
$('#profile_avatar').val(croppedImageDataURL.toDataURL("image/png"))
);
但是当我点击“剪切按钮”时,我得到了
InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
在控制台中。 我究竟做错了什么?我试图打败它几个小时。非常感谢!
带视图的超薄文件:
= form_for @profile do |f|
= f.label :avatar
= f.file_field :avatar
.canvas_window
canvas id='canvas'
.preview
= link_to('Cut', '', id: 'cut_button')
= f.label :photos
= f.file_field :photos, multiple: true
= f.label :description
= f.text_area :description
= @profile.errors.messages[:description].presence
= hidden_field :dimensions, ''
= f.submit I18n.t('user.forms.buttons.submit')
javascript:
var canvas = $("#canvas"),
context = canvas.get(0).getContext("2d"),
$result = $('#result');
$('#profile_avatar').on( 'change', function()
console.log('start')
if (this.files && this.files[0])
if ( this.files[0].type.match(/^image\//) )
var reader = new FileReader();
reader.onload = function(evt)
var img = new Image();
img.onload = function()
context.canvas.height = img.height;
context.canvas.width = img.width;
context.drawImage(img, 0, 0);
const image = document.getElementById('canvas');
const cropper = new Cropper(image,
preview: '.preview',
aspectRatio: 16 / 9,
crop(event)
dimensions = event.detail.width + 'x' + event.detail.width + '+' + event.detail.x + '+' + event.detail.y
$('#new_profile input#dimensions_').val(dimensions)
console.log(dimensions);
console.log(event.detail.x);
console.log(event.detail.y);
console.log(event.detail.width);
console.log(event.detail.height);
,
);
$('#cut_button').click(function(e)
e.preventDefault();
var croppedImageDataURL = cropper.getCroppedCanvas()
HERE IS ERROR \/
$('#profile_avatar').val(croppedImageDataURL.toDataURL("image/png"))
console.log(croppedImageDataURL.toDataURL("image/png"))
);
;
img.src = evt.target.result;
;
reader.readAsDataURL(this.files[0]);
else
alert("Invalid file type! Please select an image file.");
else
alert('No file(s) selected.');
);
html:
<form class="new_profile" id="new_profile" enctype="multipart/form-data" action="/profiles" accept-charset="UTF-8" method="post">
<input type="hidden" name="authenticity_token" value="j53mqq1th1kb17ynj2jxIMcPFRC210EQVLBSgEu2n4FLOONtFBH3Vu7wrjc+iDrogn99H/emvN5qUdyZo2pAkg==">
<label for="profile_avatar">Avatar</label>
<input type="file" name="profile[avatar]" id="profile_avatar">
<div class="canvas_window">
<canvas id="canvas"></canvas>
</div>
<div class="preview"></div>
<a id="cut_button" href="">Cut</a>
<label for="profile_photos">Photos</label>
<input multiple="multiple" type="file" name="profile[photos][]" id="profile_photos">
<label for="profile_description">Description</label>
<textarea name="profile[description]" id="profile_description"></textarea>
<input type="hidden" name="dimensions[]" id="dimensions_">
<input type="submit" name="commit" value="Submit" data-disable-with="Submit">
</form>
【问题讨论】:
请添加包含#cut_button
和#profile_avatar
的html标记。
@EdLucas,已添加
如果没有设置“cropper”对象的 JavaScript,就很难判断。另外,你能知道是哪一行JS导致了错误吗?
@EdLucas 添加了 JS 和错误的地方
【参考方案1】:
突出的一点是您需要将图像的来源设置为toDataUrl()
的输出。例如:
HTML:
<img id="cropped_image" src="/blank.gif"></img>
JS:
$("#cropped_image").attr("src", croppedImageDataURL.toDataURL("image/png"));
您可以使用 JavaScript 即时创建该图像,或者在您的标记中包含 <img/>
标记,使用空白图像或隐藏(添加裁剪后的图像后显示)。
要在表单中传递图像,您应该使用输入字段,因为此时的值是一个字符串(例如“data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNby”)。
HTML:
<input id="cropped_image" type="hidden" />
JS:
$("#cropped_image").val(croppedImageDataURL.toDataURL("image/png"));
【讨论】:
是的,但它会是一个图像标签,不是吗?如何将它发送到服务器,这就是我的意思? 对不起,我误解了你的意图。我认为您只需要使用不同的字段类型,因为图像已被toDataUrl()
缩减为字符串。见上文。
<input type="file" />
特定于文件上传。见:developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file
即使使用toBlob()
创建图像“文件”也不适用于此表单,因为您无法以编程方式设置<input type="file" />
的值:How to set a value to a file input in HTML?。
是的,你的解决方案是可行的,我得到了裁剪图像的网址,但现在我无法将此字符串转换为服务器端的图像。【参考方案2】:
如果您的服务器需要文件作为输入,请检查 this link。
整个过程是: CroppedData() -> Base64 图像 -> Blob -> 文件 ===> 发送到服务器
【讨论】:
以上是关于如何使用cropper.js 对图像应用裁剪?的主要内容,如果未能解决你的问题,请参考以下文章