Im facing this STRANGEST issue in my website. The method given below takes a base64 string and the crop, zoom and rotation values and returns a modified base64 string. This method works absolutely fine on all the android devices and desktops. But when an iPhone is used, this methods returns a base64 string that when converted is a plain black image. I have no clue why its behaving like this on all the iPhones.
Extra info : This only happens for the HEIF images that are automatically converted to jpeg when a user selects them from the iPhone's gallery. For other formats like jpg and png the method works fine even on iPhone.
Here's the crop method
async function getCroppedImg(imageSrc, pixelCrop, rotation) {
console.log('imagesrc : ', imageSrc)
const image = await createImage(imageSrc);
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const maxSize = Math.max(image.width, image.height);
const safeArea = 2 * ((maxSize / 2) * Math.sqrt(2));
canvas.width = safeArea;
canvas.height = safeArea;
ctx.translate(safeArea / 2, safeArea / 2);
ctx.rotate(getRadianAngle(rotation));
ctx.translate(-safeArea / 2, -safeArea / 2);
ctx.drawImage(
image,
safeArea / 2 - image.width * 0.5,
safeArea / 2 - image.height * 0.5
);
const data = ctx.getImageData(0, 0, safeArea, safeArea);
canvas.width = pixelCrop.width;
canvas.height = pixelCrop.height;
ctx.putImageData(
data,
0 - safeArea / 2 + image.width * 0.5 - pixelCrop.x,
0 - safeArea / 2 + image.height * 0.5 - pixelCrop.y
);
return canvas.toDataURL("image/jpeg");
}
const createImage = (url) =>
new Promise((resolve, reject) => {
const image = new Image();
image.addEventListener("load", () => resolve(image));
image.addEventListener("error", (error) => reject(error));
image.setAttribute("crossOrigin", "anonymous");
image.src = url;
});
function getRadianAngle(degreeValue) {
return (degreeValue * Math.PI) / 180;
}
What I have tried:
I confirmed that the iphone automatically converts the HEIF format to jpeg when uploaded on website. Then this jpeg is converted to valid base64 format but when its passed to this method its gives out a base64 string thats just a black image upon converting.