Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cropped section and zoom are incorrect when image is loaded from device gallery #761

Open
CodeWithOz opened this issue Aug 5, 2021 · 0 comments

Comments

@CodeWithOz
Copy link

Expected Behavior

The cropped output should be contain the area specified within the viewport and at the specified zoom.

Actual Behavior

I'm using a cordova app. If I load the image from my device gallery, the cropped output isn't set the same zoom and doesn't include the same area I set in the viewport. If, however, I take a new pic and feed that directly to croppie, then the cropped section and zoom are correct.

Steps to Reproduce the Problem

I created a repo with a sample app for this though the app has failed to build for other reasons. You can see the code here.

The relevant javascript code is:

        const sourceType = Camera.PictureSourceType.PHOTOLIBRARY;

        const cameraOptions = {
            quality: 75,
            destinationType: Camera.DestinationType.FILE_URI,
            sourceType,
            encodingType: Camera.EncodingType.JPEG,
            saveToPhotoAlbum: false,
            correctOrientation: true,
            targetWidth: 720,
            mediaType: Camera.MediaType.PICTURE,
        };

        const storageFolder = 'externalRootDirectory';
        let folderToStoreImage = cordova.file[storageFolder]; // <-- SD card on Android

        navigator.camera.getPicture(cameraSuccess, cameraError, cameraOptions);

        // Convert base64 to Blob function for image crop
        function base64toBlob(b64Data, contentType) {
            contentType = contentType || '';
            var sliceSize = sliceSize || 512;

            const byteCharacters = atob(b64Data.split(',')[1]);
            const byteArrays = [];

            for (
                let offset = 0;
                offset < byteCharacters.length;
                offset += sliceSize
            ) {
                const slice = byteCharacters.slice(offset, offset + sliceSize);

                const byteNumbers = new Array(slice.length);
                for (let i = 0; i < slice.length; i++) {
                    byteNumbers[i] = slice.charCodeAt(i);
                }

                const byteArray = new Uint8Array(byteNumbers);

                byteArrays.push(byteArray);
            }

            const blob = new Blob(byteArrays, {
                type: contentType,
            });
            return blob;
        }

        function cameraSuccess(imageURI) {
            const newImageURI = window.Ionic.WebView.convertFileSrc(imageURI);
            window.uploadCropProfile = new Croppie(
                document.querySelector('.content'),
                {
                    enableOrientation: false,
                    enableExif: true,
                    viewport: {
                        width: 200,
                        height: 200,
                        type: 'circle',
                    },
                    boundary: {
                        width: 300,
                        height: 300,
                    },
                }
            );
            uploadCropProfile.bind({
                url: newImageURI,
            });
            uploadCropProfile
                .result({
                    type: 'base64',
                    format: 'jpeg',
                    size: 'original',
                    quality: 1,
                    circle: false,
                })
                .then(function (resp) {
                    window.resolveLocalFileSystemURL(
                        folderToStoreImage,
                        function (dirEntry) {
                            // Setup filename and assume a jpg file
                            const filename =
                                Math.floor(Math.random() * 100 + 1) +
                                '-image.jpg';
                            console.log('File name cropped ', filename);
                            // Get file and create if it's not available
                            dirEntry.getFile(
                                filename,
                                {
                                    create: true,
                                    exclusive: false,
                                },
                                function (fileEntry) {
                                    // convert base64 data to jpg
                                    let binary = base64toBlob(resp, 'jpg');

                                    // store created jpg file
                                    fileEntry.createWriter(function (
                                        fileWriter
                                    ) {
                                        // Write file end function
                                        fileWriter.onwriteend = function () {
                                            console.log('Writing done');
                                            // store and get it's path
                                            const croppedImageURL =
                                                fileEntry.nativeURL;

                                            // send cropped image URL in callback
                                            cb(croppedImageURL);
                                            uploadCropProfile.destroy();
                                        };

                                        fileWriter.onerror = function (e) {
                                            console.log('Writing error ', e);
                                        };

                                        // If data object is not passed in,
                                        // create a new Blob instead.
                                        if (!binary) {
                                            binary = new Blob(
                                                ['missing data'],
                                                {
                                                    type: 'text/plain',
                                                }
                                            );
                                        }
                                        // Write file call
                                        fileWriter.write(binary);
                                    });
                                },
                                function (errorCreateFile) {
                                    console.error(errorCreateFile);
                                }
                            );
                        },
                        function (errorCreateFS) {
                            console.error(
                                'Error getting filesystem:',
                                errorCreateFS
                            );
                        }
                    );
                });
        }

        function cameraError(message) {
            console.error(
                'Camera error:', message
            );
            if (typeof errCb === 'function') {
                errCb(message);
            }
        }

Example Link

Please recreate your issue using JSbin, JSFiddle, or Codepen.

Specifications

  • Browser: Chrome webview
  • Version: 92
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant