scottcheng / cropit

A "customizable crop and zoom" jQuery plugin.
http://scottcheng.github.io/cropit/
MIT License
874 stars 305 forks source link

Copit export image is off by 1 pixel in height and width #205

Open pierregangloff opened 8 years ago

pierregangloff commented 8 years ago

Hi! We have a strange issue. Only 2 users (out of 900 users) reported this: cropit export sends an image that is off by one pixel in width and height. So, I'm guessing this might be a problem on a specific browser/OS combination.

The problem: our code tells cropit to export the image with width: 280 and height: 296. My backend code validates that, in fact, an image of that width/height comes in and no user should ever get a backend validation error telling the user that the image is of the wrong size (unless they circumvent the UI and try funny things, in which case they'd get the validation error). But some users, when going through the UI infact get the validation error because the image that the UI (cropit) is sending to the backend is off by one pixel in width and height. For those users, cropit sends an image of width=279 and height=295.

Our quick fix is to be more tolerant and accept images 2 pixels larger/wider in either direction (so we now accept an uploaded image of width between 278 and 282 and height between 294 and 298) to account for the fact that cropit might send us an image slightly off by one pixel (we made it a to avoid the ache to the users IF EVER some browser messes it by 2 pixels).

Any ideas? Has anyone seen this? You think it's a browser thing too? Oh, and I heard back from one user, they are using Firefox on Windows10 (from a screenshot, need to get FF version). Trying to find browser/OS of the other user.

Here's my full code. Notice that I'm doing a backend server request upon "image select" to resize the image to a more manageable image size if/when the user select a really large image [ex: 5MB] which sometimes caused the browser to freeze [especially true with Chrome when inspect tools are on] or even crashed once on my iphone 5 and on my QA person's android. But that initial server resize should have no impact on how cropit then exports this image.

<script>
    $(function() {

        var profilePhotoCropper = $('#image-cropper');
        var photoLoadingSpinner = $('#image-loading-gears');

        function showSpinner() {
            photoLoadingSpinner.css('visibility', 'visible');
        }
        function hideSpinner() {
            photoLoadingSpinner.css('visibility', 'hidden');
        }

        profilePhotoCropper.cropit({
            smallImage: 'allow',
            //initialZoom: 'image',
            minZoom: 'fit',
            maxZoom: 3.0,
            imageBackground: true,
            imageBackgroundBorderWidth: 15, // Width of background border
            onFileChange : function fileChange(e) {
            },
            onImageLoading : function loading(e) {
                showSpinner();
            },
            onImageLoaded :function loaded(e) {
                hideSpinner();
            },
            imageState: {
              src: '<c:url value="/images/default-profile-image.jpg"/>'
            }
        });

        $('#imageFileInput').change(function(e) {
            $('#resizeErrorDialog').css('display', 'none');
            showSpinner();
            // send the "potentially LARGE" image to the backend to get
            // back a more manageable/smaller version.
            var data = new FormData();
            $.each($('#imageFileInput')[0].files, function(i, file) {
                data.append('file-'+i, file);
            });
            // POST to the servlet
            $.ajax({
                url: '<c:url value="/viewPhoto"/>',
                data: data,
                cache: false,
                contentType: false,
                processData: false,
                type: 'POST',
                success: function(data){
                    // set the BASE64 image returned by the Servlet
                    profilePhotoCropper.cropit('imageSrc', data);
                    hideSpinner();
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    $('#resizeErrorDialog').css('display', 'block');
                    hideSpinner();
                }
            });
        });

        // When user clicks select image button,
        // open select file dialog programmatically
        $('#select-image-btn').click(function() {
            $('#imageFileInput').click();
        });

        $('#save-image-btn').click(function() {
            showSpinner();
            // get the CROPPED image data
            var imageData = profilePhotoCropper.cropit('export', {
                type: 'image/jpeg',
                quality: 1.0,
                originalSize: false,
                width: 280,
                height: 296
            });
            //window.open(imageData);
            $('#imageInBase64').val(imageData);
            $('#formInputMode').val("publishDirect");
            document.forms[0].submit();
        });

        // Handle rotation
        $('.rotate-cw-btn').click(function() {
            profilePhotoCropper.cropit('rotateCW');
        });
        $('.rotate-ccw-btn').click(function() {
            profilePhotoCropper.cropit('rotateCCW');
        });
    });
</script>

Thanks for any thoughts, suggestions, complaints ;-)

Pierre

andrewjwaggoner commented 7 years ago

Hey, I know this is late but I believe the issue you are facing is due to the zoom setting in the browser. We have noticed that if it is not set to 100% our exports become off by 1. We are also getting similar issues when this is with a 4k monitor.