ValentinH / react-easy-crop

A React component to crop images/videos with easy interactions
https://valentinh.github.io/react-easy-crop/
MIT License
2.34k stars 167 forks source link

Square image in ios #521

Closed Goowwy closed 8 months ago

Goowwy commented 8 months ago

Describe the bug Ios upload only square image not depend as aspect ratio

To Reproduce Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior A clear and concise description of what you expected to happen.

ValentinH commented 8 months ago

I don't understand. The issue template is here for a reason.

Goowwy commented 8 months ago

Этот код обрезает на iPhone только центр фотографии, либо грузит только черный фон, добавил разделение на сафари но это не помогло Можешь помочь с этим? Заранее благодарю!

// Function to create an image object from URL
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"); // needed to avoid cross-origin issues on CodeSandbox
    image.src = url;
  });

// Function to convert degrees to radians
function getRadianAngle(degreeValue) {
  return (degreeValue * Math.PI) / 180;
}

// Check if the user agent is Safari
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);

// Main function to crop image
export default async function getCroppedImg(imageSrc, pixelCrop, rotation = 0) {
  const image = await createImage(imageSrc);
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");

  // Calculate the maximum size of the image
  const maxSizeOrigin = Math.max(image.width, image.height);
  // Determine the divisor based on the desired aspect ratio (3:4)
  const aspectRatio = 3 / 4;
  const divide = maxSizeOrigin < 4000 ? 2 : maxSizeOrigin < 6000 ? 3 : maxSizeOrigin > 8000 ? 4 : 6;
  const maxSize = isSafari ? Math.max(image.width, image.height) / divide : Math.max(image.width, image.height);

  // Calculate the safe area for rotating the image without clipping
  const safeWidth = aspectRatio < 1 ? maxSize * aspectRatio : maxSize;
  const safeHeight = aspectRatio > 1 ? maxSize / aspectRatio : maxSize;

  // Set canvas dimensions to the safe area size
  canvas.width = safeWidth;
  canvas.height = safeHeight;

  // Translate canvas context to a central location on image to allow rotating around the center
  ctx.translate(safeWidth / 2, safeHeight / 2);
  ctx.rotate(getRadianAngle(rotation));
  ctx.translate(-safeWidth / 2, -safeHeight / 2);

  // Draw rotated image and store data
  ctx.drawImage(
    image,
    safeWidth / 2 - image.width * 0.5,
    safeHeight / 2 - image.height * 0.5
  );

  const data = ctx.getImageData(0, 0, safeWidth, safeHeight);

  // Set canvas width and height to the final desired crop size
  canvas.width = pixelCrop.width;
  canvas.height = pixelCrop.height;

  // Paste rotated image with correct offsets for x,y crop values
  ctx.putImageData(
    data,
    0 - safeWidth / 2 + image.width * 0.5 - pixelCrop.x,
    0 - safeHeight / 2 + image.height * 0.5 - pixelCrop.y
  );

  // Return the cropped image as a canvas element
  return canvas;
}

// Function to generate download of cropped image
export const generateDownload = async (imageSrc, crop) => {
  if (!crop || !imageSrc) {
    return;
  }

  const canvas = await getCroppedImg(imageSrc, crop);

  canvas.toBlob(
    (blob) => {
      const previewUrl = window.URL.createObjectURL(blob);

      const anchor = document.createElement("a");
      anchor.download = "image.jpeg";
      anchor.href = URL.createObjectURL(blob);
      anchor.click();

      window.URL.revokeObjectURL(previewUrl);
    },
    "image/jpeg",
    0.66
  );
};