[英]How can I use cropme.js to allow users upload their profile image?
这是一个知识共享问答。
Cropme是一个不错的 JS 插件,用于使用可视滑块裁剪和旋转图像。 作者提供了很好的文档,但是构建一个有效的实现并不像它应该的那么简单。
我想回答的问题是这样的:
我想允许我的网站用户上传他们的个人资料图片。 该图像必须恰好为 240x292 像素。 用户应该能够缩放和旋转他们的图像,然后将其裁剪为特定尺寸并将其上传到我的网站。 我怎么能用crome做所有这些?
这些是需要的步骤:
那么我们该怎么做呢?
https://codepen.io/ishahak/pen/XWjVzLr
我将逐步解释一些细节。
注意:通常在我的代码中,当您看到obj[0]时,它只是从 jQuery object 转换为简单的 JS object。
我们可以使用以下代码即时创建真正的 SVG 图像:
getImagePlaceholder: function(width, height, text) {
//based on https://cloudfour.com/thinks/simple-svg-placeholder/
var svg = '\
<svg xmlns="http://www.w3.org/2000/svg" width="{w}" \
height="{h}" viewBox="0 0 {w} {h}">\
<rect fill="#ddd" width="{w}" height="{h}"/>\
<text fill="rgba(0,0,0,0.5)" font-family="sans-serif"\
font-size="30" dy="10.5" font-weight="bold"\
x="50%" y="50%" text-anchor="middle">{t}</text>\
</svg>';
var cleaned = svg
.replace(/{w}/g, width)
.replace(/{h}/g, height)
.replace('{t}', text)
.replace(/[\t\n\r]/gim, '') // Strip newlines and tabs
.replace(/\s\s+/g, ' ') // Condense multiple spaces
.replace(/'/gim, '\\i'); // Normalize quotes
var encoded = encodeURIComponent(cleaned)
.replace(/\(/g, '%28') // Encode brackets
.replace(/\)/g, '%29');
return 'data:image/svg+xml;charset=UTF-8,' + encoded;
}
这个过程涉及一个“文件”类型的输入元素,它没有可见的外观(我们使用“d-none”类设置它),以及一个“点击”它以打开对话框的按钮元素:
<button id="btnGetImage" class="btn btn-primary">Get Image</button>
<input class="d-none" type="file" id="fileUpload" accept="image/*" />
以及相关代码:
$('#btnGetImage').on('click', function(){
//force 'change' event even if repeating same file:
$('#fileUpload').prop("value", "");
$('#fileUpload').click();
});
$('#fileUpload').on('change', function(){
CiM.read_file_from_input(/*input elem*/this, function() {
console.log('image src fully loaded');
$('#imgModal-dialog').modal('show');
});
});
当一个文件被选中时,'change' 事件被触发,导致我们将文件读入 memory。
我们上面提到的read_file_from_input是这样实现的:
imgHolder: null,
imgHolderCallback: null,
read_file_from_input: function(input, callback) {
if (input.files && input.files[0]) {
imgHolderCallback = callback;
var reader = new FileReader();
if (!CiM.imgHolder) {
CiM.imgHolder = new Image();
CiM.imgHolder.onload = function () {
if (imgHolderCallback) {
imgHolderCallback();
}
}
}
reader.onload = function (e) {
console.log('image data loaded!');
CiM.imgHolder.src = e.target.result; //listen to img:load...
}
reader.readAsDataURL(input.files[0]);
}
else {
console.warn('failed to read file');
}
}
当 FileReader 准备好时,我们为我们的内部图像持有者设置src ,并等待“加载”事件,这表明img元素已准备好接收新内容。
我们监听那个“加载”事件,当触发时我们显示模态。 Bootstrap 中的模式有几个事件。 我们听那个表示模态显示的信号,这意味着宽度和设置,我们可以根据它来计划我们的 Cropme 尺寸。
update_options_for_width: function(w) {
var o = CiM.opt, //shortcut
vp_ratio = o.my_final_size.w / o.my_final_size.h,
h, new_vp_w, new_vp_h;
w = Math.floor(w * 0.9);
h = Math.floor(w / o.my_win_ratio);
o.container.width = w;
o.container.height = h;
new_vp_h = 0.6 * h;
new_vp_w = new_vp_h * vp_ratio;
// if we adapted to the height, but it's too wide:
if (new_vp_w > 0.6 * w) {
new_vp_w = 0.6 * w;
new_vp_h = new_vp_w / vp_ratio;
}
new_vp_w = Math.floor(new_vp_w);
new_vp_h = Math.floor(new_vp_h);
o.viewport.height = new_vp_h;
o.viewport.width = new_vp_w;
}
我们等待设置模态框的大小,因为必须使用特定的视口尺寸设置crome 。 在我们的showed.bs.modal处理程序结束时,我们创建我们的Cropme实例。
这是保存按钮处理程序:
$('#imgModal-btnSave').on('click', function(){
uploadImage(croppedImg[0], function(path_to_saved) {
savedImg[0].src = path_to_saved;
$('#imgModal-dialog').modal('hide');
});
});
uploadImage function 是这样的:
uploadImage: function(img, callback){
var imgCanvas = document.createElement("canvas"),
imgContext = imgCanvas.getContext("2d");
// Make sure canvas is as big as the picture (needed??)
imgCanvas.width = img.width;
imgCanvas.height = img.height;
// Draw image into canvas element
imgContext.drawImage(img, 0, 0, img.width, img.height);
var dataURL = imgCanvas.toDataURL();
$.ajax({
type: "POST",
url: "save-img.php", // see code at the bottom
data: {
imgBase64: dataURL
}
}).done(function(resp) {
if (resp.startsWith('nok')) {
console.warn('got save error:', resp);
} else {
if (callback) callback(resp);
}
});
}
它与一个简单的 PHP 脚本相匹配,该脚本出现在 codepen 中HTML的末尾。 我认为这个答案太长了,所以我会在这里完成。
祝你好运 - 玩得开心:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.