在 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的主要内容,如果未能解决你的问题,请参考以下文章

jcrop宽度,高度通过输入数值调整?

jCrop 在更改图像时使用正确的坐标调整大小

图像旋转和 Jcrop.js

JCrop 裁剪错误区域

如何修复这个 AngularJS JCrop 指令?

Jcrop 与主干/jquery