在 Jcrop 中需要帮助 - 类 jcrop-tracker
Posted
技术标签:
【中文标题】在 Jcrop 中需要帮助 - 类 jcrop-tracker【英文标题】:Need help in Jcrop - Class jcrop-tracker 【发布时间】:2021-05-02 16:42:27 【问题描述】:我开发了一个使用实时摄像头和上传文件的图片捕捉 WebApp。
除了以下用例外,它工作正常:
-
使用实时相机拍摄照片。
图片已设置为裁剪。
裁剪图像后,将在右侧列中捕获图像。
现在,当您使用实时相机重新捕获图像时 - 新图像将根据裁剪坐标显示。
我试图找到根本原因,但无法找到它为什么会这样。
这里是 html 代码及其 javascript 代码,以及小提琴:https://jsfiddle.net/w6ahp7k9/
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Upload Image</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-jcrop/0.9.9/js/jquery.Jcrop.min.js"></script>
<style>
.center
text-align: center;
</style>
<script type="text/javascript">
$(function ()
//Create variables (in this scope) to hold the Jcrop API and image size
var jcrop_api, boundx, boundy;
//#region WebCam
// Grab elements, create settings, etc.
let video = document.getElementById('video');
// Get access to the camera!
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia)
// Not adding ` audio: true ` since we only want video now
navigator.mediaDevices.getUserMedia( video: true ).then(function (stream)
//video.src = window.URL.createObjectURL(stream);
video.srcObject = stream;
video.play();
);
// Elements for taking the snapshot
let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');
// Trigger photo take
document.getElementById("btnCapture").addEventListener("click", function ()
//Set Ratio
var ratio;
var width = 600;//window.innerWidth;
var height = 600;//window.innerHeight;
if (video.width > width)
ratio = width / video.width;
else if (video.height > height)
ratio = height / video.height;
else
ratio = 1;
context.drawImage(video, 0, 0, video.width * ratio, video.height * ratio);
console.log('Video w:' + video.width * ratio);
console.log('Video h:' + video.height * ratio);
//Set the canvas to Image1
$("#Image1")[0].src = canvas.toDataURL();
$("#Image1").show();
$("#canvas").hide();
// destroy Jcrop if it is existed
if (typeof jcrop_api != 'undefined')
jcrop_api.destroy();
jcrop_api = null;
$('#Image1').Jcrop(
onChange: SetCoordinates,
onSelect: SetCoordinates
,
function ()
// use the Jcrop API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the Jcrop API in the jcrop_api variable
jcrop_api = this;
);
);
//#endregion WebCam
//#region FileUpload, Resize, JCrop, Crop & Clear
$('#FileUpload1').change(function (event)
try
var files = event.target.files;
var file = files[0];
console.log('FileUpload1 Length:' + files.length);
if (file)
$('#Image1').hide();
var reader = new FileReader();
reader.onload = function (e)
//$('#Image1').show();
$('#Image1').attr("src", e.target.result);
;
reader.readAsDataURL($(this)[0].files[0]);
//#region Resize & JCrop
var reader = new FileReader();
// Set the image for the FileReader
reader.onload = function (e)
var img = document.createElement("img");
img.src = e.target.result;
// Create your canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var MAX_WIDTH = 400;
var MAX_HEIGHT = 400;
let width = img.width;
let height = img.height;
console.log('Image w & h:' + width + '-' + height);
if (width == 0 && height == 0)
throw new UserException("An internal error occured - please try again or contact your administrator!");
return;
// Add the resizing logic
if (width > height)
if (width > MAX_WIDTH)
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
else
if (height > MAX_HEIGHT)
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
//Specify the resizing result
canvas.width = width;
canvas.height = height;
console.log('Canvas w & h:' + canvas.width + '-' + canvas.height);
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
dataurl = canvas.toDataURL(file.type);
document.getElementById("Image1").src = dataurl;
$('#Image1').show();
// destroy Jcrop if it is existed
if (typeof jcrop_api != 'undefined')
jcrop_api.destroy();
jcrop_api = null;
$('#Image1').Jcrop(
onChange: SetCoordinates,
onSelect: SetCoordinates
,
function ()
// use the Jcrop API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the Jcrop API in the jcrop_api variable
jcrop_api = this;
);
;
reader.readAsDataURL(file);
//#endregion Resize & JCrop
catch (err)
alert(err.message);
);
$('#btnCrop').click(function ()
var x1 = $('#imgX1').val();
var y1 = $('#imgY1').val();
var width = $('#imgWidth').val();
var height = $('#imgHeight').val();
var canvas = $("#canvas")[0];
var context = canvas.getContext('2d');
var img = new Image();
img.onload = function ()
canvas.height = height;
canvas.width = width;
context.drawImage(img, x1, y1, width, height, 0, 0, width, height);
$('#imgCropped').val(canvas.toDataURL());
$("#capturedImage")[0].src = canvas.toDataURL();
document.getElementById("<%=ImgExSrc.ClientID%>").value = canvas.toDataURL();
document.getElementById("btnSubmit").disabled = true;
$('#btnSubmit').show();
$('#lblTermsConditions').show();
$('#chkApprove').show();
;
img.src = $('#Image1').attr("src");
$("#canvas").hide();
);
$('#btnClear').click(function ()
Clear();
);
//#endregion FileUpload, Resize, JCrop, Crop & Clear
);
function Clear()
$('#Image1').attr('src', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==');
$("div.jcrop-holder").remove();
$("div.jcrop-tracker").remove();
$('#btnCrop').hide();
$('#btnClear').hide();
function SetCoordinates(c)
$('#imgX1').val(c.x);
$('#imgY1').val(c.y);
$('#imgWidth').val(c.w);
$('#imgHeight').val(c.h);
$('#btnCrop').show();
$('#btnClear').show();
;
function UserException(message)
alert(message);
console.log(message);
</script>
</head>
<body>
<form id="form2" runat="server">
<div class="container">
<div class="jumbotron">
<h1>Upload Image</h1>
<p class="lead">This application offer to capture image along with crop functionality using either a Live Camera or an Upload File Control.</p>
</div>
<div class="row">
<div class="col-md-4" style="background-color: lavender;">
<div class="center">
<p><b>Live Camera</b></p>
<video id="video" autoplay></video>
<br />
<input type="button" id="btnCapture" value="Capture" />
<br />
<br />
</div>
</div>
<div class="col-md-4" style="background-color: orange;">
<div class="center">
<p><b>Upload File</b></p>
<input type="file" id="FileUpload1" accept=".jpg,.png,.gif" />
<br />
<br />
</div>
<table class="table" border="0">
<tbody>
<tr>
<td>
<img id="Image1" src="" style="display: none" />
</td>
<td>
<canvas id="canvas" ></canvas>
</td>
</tr>
</tbody>
</table>
<br />
<input type="hidden" name="imgX1" id="imgX1" />
<input type="hidden" name="imgY1" id="imgY1" />
<input type="hidden" name="imgWidth" id="imgWidth" />
<input type="hidden" name="imgHeight" id="imgHeight" />
<input type="hidden" name="imgCropped" id="imgCropped" />
<div class="align-items-center">
<input type="button" id="btnCrop" value="Crop" style="display: none" />
<input type="button" id="btnClear" value="Clear" style="display: none" />
<br />
<br />
</div>
</div>
<div class="col-md-4" style="background-color: lavender;">
<div class="center">
<p><b>Captured Image</b></p>
<img id="capturedImage" src="" runat="server" />
<asp:HiddenField runat="server" ID="ImgExSrc" />
<br />
<br />
<input type="checkbox" id="chkApprove" onchange="document.getElementById('btnSubmit').disabled = !this.checked;" style="display: none">
<asp:Label ID="lblTermsConditions" runat="server" Style="display: none" Text="I have read and understood the declaration of consent. I agree to the terms and conditions."></asp:Label>
<br />
<br />
<asp:Button ID="btnSubmit" OnClick="btnSubmit_Click" runat="server" Text="Submit" Style="display: none" />
<br />
<br />
</div>
</div>
</div>
</div>
</form>
</body>
</html>
【问题讨论】:
【参考方案1】:这是最终代码 - 工作代码:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head >
<title>Upload Image</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-jcrop/0.9.9/js/jquery.Jcrop.min.js"></script>
<style>
.center
text-align: center;
</style>
<script type="text/javascript">
$(function ()
//Create variables (in this scope) to hold the Jcrop API and image size
var jcrop_api, boundx, boundy;
//#region WebCam
// Grab elements, create settings, etc.
let video = document.getElementById('video');
// Get access to the camera!
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia)
// Not adding ` audio: true ` since we only want video now
navigator.mediaDevices.getUserMedia( video: true ).then(function (stream)
//video.src = window.URL.createObjectURL(stream);
video.srcObject = stream;
video.play();
);
// Elements for taking the snapshot
let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');
// Trigger photo take
document.getElementById("btnCapture").addEventListener("click", function ()
//Set Ratio
var ratio;
var width = 600;//window.innerWidth;
var height = 600;//window.innerHeight;
if (video.width > width)
ratio = width / video.width;
else if (video.height > height)
ratio = height / video.height;
else
ratio = 1;
context.drawImage(video, 0, 0, video.width * ratio, video.height * ratio);
console.log('Video w:' + video.width * ratio);
console.log('Video h:' + video.height * ratio);
//Set the canvas to Image1
$("#Image1")[0].src = canvas.toDataURL();
$("#Image1").show();
$("#canvas").hide();
// destroy Jcrop if it is existed
if (typeof jcrop_api != 'undefined')
jcrop_api.destroy();
jcrop_api = null;
$('#Image1').Jcrop(
onChange: SetCoordinates,
onSelect: SetCoordinates
,
function ()
// use the Jcrop API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the Jcrop API in the jcrop_api variable
jcrop_api = this;
);
);
//#endregion WebCam
//#region FileUpload, Resize, JCrop, Crop & Clear
$('#FileUpload1').change(function (event)
try
var files = event.target.files;
var file = files[0];
console.log('FileUpload1 Length:' + files.length);
if (file)
$('#Image1').hide();
var reader = new FileReader();
reader.onload = function (e)
//$('#Image1').show();
$('#Image1').attr("src", e.target.result);
;
reader.readAsDataURL($(this)[0].files[0]);
//#region Resize & JCrop
var reader = new FileReader();
// Set the image for the FileReader
reader.onload = function (e)
var img = document.createElement("img");
img.src = e.target.result;
// Create your canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var MAX_WIDTH = 400;
var MAX_HEIGHT = 400;
let width = img.width;
let height = img.height;
console.log('Image w & h:' + width + '-' + height);
if (width == 0 && height == 0)
throw new UserException("An internal error occured - please try again or contact your administrator!");
return;
// Add the resizing logic
if (width > height)
if (width > MAX_WIDTH)
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
else
if (height > MAX_HEIGHT)
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
//Specify the resizing result
canvas.width = width;
canvas.height = height;
console.log('Canvas w & h:' + canvas.width + '-' + canvas.height);
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
dataurl = canvas.toDataURL(file.type);
document.getElementById("Image1").src = dataurl;
$('#Image1').show();
// destroy Jcrop if it is existed
if (typeof jcrop_api != 'undefined')
jcrop_api.destroy();
jcrop_api = null;
$('#Image1').Jcrop(
onChange: SetCoordinates,
onSelect: SetCoordinates
,
function ()
// use the Jcrop API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the Jcrop API in the jcrop_api variable
jcrop_api = this;
);
;
reader.readAsDataURL(file);
//#endregion Resize & JCrop
catch (err)
alert(err.message);
);
$('#btnCrop').click(function ()
var x1 = $('#imgX1').val();
var y1 = $('#imgY1').val();
var width = $('#imgWidth').val();
var height = $('#imgHeight').val();
var canvas = $("#canvas")[0];
var context = canvas.getContext('2d');
var img = new Image();
img.onload = function ()
canvas.height = height;
canvas.width = width;
context.drawImage(img, x1, y1, width, height, 0, 0, width, height);
$('#imgCropped').val(canvas.toDataURL());
$("#capturedImage")[0].src = canvas.toDataURL();
document.getElementById("<%=ImgExSrc.ClientID%>").value = canvas.toDataURL();
document.getElementById("btnSubmit").disabled = true;
$('#btnSubmit').show();
$('#lblTermsConditions').show();
$('#chkApprove').show();
//Reset the canvas height & width
console.log('before:' + canvas.height + '-' + canvas.width);
canvas.height = 380;
canvas.width = 380;
console.log('after:' + canvas.height + '-' + canvas.width);
;
img.src = $('#Image1').attr("src");
$("#canvas").hide();
);
$('#btnClear').click(function ()
Clear();
);
//#endregion FileUpload, Resize, JCrop, Crop & Clear
);
function Clear()
$('#Image1').attr('src', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==');
$("div.jcrop-holder").remove();
$("div.jcrop-tracker").remove();
$('#btnCrop').hide();
$('#btnClear').hide();
function SetCoordinates(c)
$('#imgX1').val(c.x);
$('#imgY1').val(c.y);
$('#imgWidth').val(c.w);
$('#imgHeight').val(c.h);
$('#btnCrop').show();
$('#btnClear').show();
;
function UserException(message)
alert(message);
console.log(message);
</script>
</head>
<body>
<form id="form2" >
<div class="container">
<div class="jumbotron">
<h1>Upload Image</h1>
<p class="lead">This application offer to capture image along with crop functionality using either a Live Camera or an Upload File Control.</p>
</div>
<div class="row">
<div class="col-md-4" style="background-color: lavender;">
<div class="center">
<p><b>Live Camera</b></p>
<video id="video" autoplay></video>
<br />
<input type="button" id="btnCapture" value="Capture" />
<br />
<br />
</div>
</div>
<div class="col-md-4" style="background-color: orange;">
<div class="center">
<p><b>Upload File</b></p>
<input type="file" id="FileUpload1" accept=".jpg,.png,.gif" />
<br />
<br />
</div>
<table class="table" border="0">
<tbody>
<tr>
<td>
<img id="Image1" src="" style="display: none" />
</td>
<td>
<canvas id="canvas" ></canvas>
</td>
</tr>
</tbody>
</table>
<br />
<input type="hidden" name="imgX1" id="imgX1" />
<input type="hidden" name="imgY1" id="imgY1" />
<input type="hidden" name="imgWidth" id="imgWidth" />
<input type="hidden" name="imgHeight" id="imgHeight" />
<input type="hidden" name="imgCropped" id="imgCropped" />
<div class="align-items-center">
<input type="button" id="btnCrop" value="Crop" style="display: none" />
<input type="button" id="btnClear" value="Clear" style="display: none" />
<br />
<br />
</div>
</div>
<div class="col-md-4" style="background-color: lavender;">
<div class="center">
<p><b>Captured Image</b></p>
<img id="capturedImage" src="" />
<asp:HiddenField runat="server" ID="ImgExSrc" />
<br />
<br />
<input type="checkbox" id="chkApprove" onchange="document.getElementById('btnSubmit').disabled = !this.checked;" style="display: none">
<asp:Label ID="lblTermsConditions" runat="server" Style="display: none" Text="I have read and understood the declaration of consent. I agree to the terms and conditions."></asp:Label>
<br />
<br />
<asp:Button ID="btnSubmit" OnClientClick="alert('Submitted successfully!'); return false;" runat="server" Text="Submit" Style="display: none" />
<br />
<br />
</div>
</div>
</div>
</div>
</form>
</body>
</html>
【讨论】:
以上是关于在 Jcrop 中需要帮助 - 类 jcrop-tracker的主要内容,如果未能解决你的问题,请参考以下文章