首页 > 解决方案 > 在 Jcrop 中需要帮助 - 类 jcrop-tracker

问题描述

我已经使用 Live Camera 和 Upload File 开发了一个 Picture Capture WebApp。

除了以下用例外,它工作正常:

  1. 使用实时相机拍摄照片。
  2. 图片设置为裁剪。
  3. 裁剪图像后,将在右侧栏中捕获图像。
  4. 现在,当您使用实时相机重新捕获图像时 - 新图像将根据裁剪坐标显示。

我试图找到根本原因,但无法找到它为什么会这样。

这是 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" width="400" height="400" 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" height="380" width="380"></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>

标签: jqueryjcrop

解决方案


这是最终代码 - 工作代码:

<!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" width="400" height="400" 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" height="380" width="380"></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>

推荐阅读