Cropped section and zoom are incorrect when image is loaded from device gallery
CodeWithOz opened this issue · 0 comments
CodeWithOz commented
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