我正在开发一个具有文件上传HTML控件的组件,使用该控件选择图像后,该图像将呈现在HTML5 Canvas元素上
id = target 是jcrop图像目标 id = photograph 是文件上传控件 id =预览 是canvas元素 id = clear_selection 是一个可以清除画布的按钮
使用的第三方JS库:
<script src="./js/jquery.min.js"></script> <script src="./js/jquery.Jcrop.js"></script> <script src="./js/jquery.color.js"></script>
设置JCrop:
<script type="text/javascript"> jQuery(function($){ var api; $('#target').Jcrop({ // start off with jcrop-light class bgOpacity: 0.5, keySupport: false, bgColor: 'black', minSize:[240,320], maxSize:[480,640], onChange : updatePreview, onSelect : updatePreview, height:160, width:120, addClass: 'jcrop-normal' },function(){ api = this; api.setSelect([0,0,240,320]); api.setOptions({ bgFade: true }); api.ui.selection.addClass('jcrop-selection'); }); });
清除画布按钮单击事件:
jQuery('#clear_selection').click(function(){ $('#target').Jcrop({ setSelect: [0,0,0,0], }); });
在jcrop面板上显示上传的图像
function readURL(input) { if (input.files && input.files[0]) { var reader = new FileReader(); reader.onload = function (e) { $('#target').attr('src', e.target.result); setProperties(); } reader.readAsDataURL(input.files[0]); } } function setProperties(){ $('#target').Jcrop({ setSelect: [0,0,240,320] }); } $("#photograph").change(function(){ readURL(this); });
我正在使用以下代码在画布上裁剪和渲染图像。
function make_base() { console.log("make_base called"); var base_image = new Image(); base_image.src = ''; base_image.onload = function () { context.drawImage(base_image, 0, 0); } } var canvas = document.getElementById('preview'), context = canvas.getContext('2d'); make_base(); function updatePreview(c) { console.log("called"); if(parseInt(c.w) > 0) { // Show image preview var imageObj = $("#target")[0]; var canvas = $("#preview")[0]; var context = canvas.getContext("2d"); context.drawImage(imageObj, c.x, c.y, c.w, c.h, 0, 0, canvas.width, canvas.height); } };
这是我在上述设置中面临的一系列问题:
HTML5
Seahorsepip的答案很棒。我对非后备答案做了很多改进。
我建议您不要做一个奇怪的隐藏png事情,当一个Image对象也可以工作的时候(只要我们不支持后备)。
var jcrop_api; var canvas; var context; var image; var prefsize;
即使是这样,您最好还是从画布上移出该数据,而仅在最后将其放入该字段中。
function loadImage(input) { if (input.files && input.files[0]) { var reader = new FileReader(); reader.onload = function(e) { image = new Image(); image.src = e.target.result; validateImage(); } reader.readAsDataURL(input.files[0]); } }
但是,如果您想要的不仅仅是裁剪功能,我们还可以将jcrop附加到插入的画布上(在刷新时将使用jcrop销毁它)。我们可以轻松地完成我们可以使用画布执行的任何操作,然后再次执行validateImage()并使更新的图像可见。
function validateImage() { if (canvas != null) { image = new Image(); image.src = canvas.toDataURL('image/png'); } if (jcrop_api != null) { jcrop_api.destroy(); } $("#views").empty(); $("#views").append("<canvas id=\"canvas\">"); canvas = $("#canvas")[0]; context = canvas.getContext("2d"); canvas.width = image.width; canvas.height = image.height; context.drawImage(image, 0, 0); $("#canvas").Jcrop({ onSelect: selectcanvas, onRelease: clearcanvas, boxWidth: crop_max_width, boxHeight: crop_max_height }, function() { jcrop_api = this; }); clearcanvas(); }
然后在提交时,我们提交任何未决的操作,例如applyCrop()或applyScale(),如果需要的话,将数据添加到备用字段的隐藏字段中。然后我们有了一个系统,我们可以轻松地以任何方式修改画布,然后在提交画布时正确发送数据。
function applyCrop() { canvas.width = prefsize.w; canvas.height = prefsize.h; context.drawImage(image, prefsize.x, prefsize.y, prefsize.w, prefsize.h, 0, 0, canvas.width, canvas.height); validateImage(); }
画布被添加到div视图中。
<div id="views"></div>
为了捕获PHP(drupal)中的附件,我使用了类似的方法:
function makeFileManaged() { if (!isset($_FILES['croppedfile'])) return NULL; $path = $_FILES['croppedfile']['tmp_name']; if (!file_exists($path)) return NULL; $result_filename = $_FILES['croppedfile']['name']; $uri = file_unmanaged_move($path, 'private://' . $result_filename, FILE_EXISTS_RENAME); if ($uri == FALSE) return NULL; $file = File::Create([ 'uri' => $uri, ]); $file->save(); return $file->id(); }