Comments (9)
I included replication instructions in the issue- very easy to reproduce it.
I believe it has to do with Safari/iOS having a max size for canvases and any larger image (basically anything taken on an iPhone) causes toBlob to quietly fail and return null.
I ended up having to move my image cropping to the server because this bug was effecting so many users.
from react-image-crop.
Hey All, just in case anyone else runs into this issue here is what I did, if you seen any flaws please respond to the comment 😅 .
import canvasSize from 'canvas-size'
export const processFile = async (
crop: Crop,
previewCanvasRef: HTMLCanvasElement,
image: HTMLImageElement
) => {
const ctx = previewCanvasRef.getContext('2d')
if (!ctx || !crop) {
return
}
const area = await canvasSize.maxArea()
const constraints = area.success
? {
height: area.height,
width: area.width,
pixels: area.height * area.width,
}
: { height: 4096, width: 4096, pixels: 4096 * 4096 }
const pixelRatio = window.devicePixelRatio || 1
const scaleX = image.naturalWidth / image.width
const scaleY = image.naturalHeight / image.height
const cropWidth = crop.width * scaleX * pixelRatio
const cropHeight = crop.height * scaleY * pixelRatio
const cropAspectRatio = cropWidth / cropHeight
let resizedCropWidth = cropWidth
let resizedCropHeight = cropHeight
if (resizedCropWidth > constraints.width) {
resizedCropWidth = constraints.width
resizedCropHeight = resizedCropWidth / cropAspectRatio
}
if (resizedCropHeight > constraints.height) {
resizedCropHeight = constraints.height
resizedCropWidth = resizedCropHeight * cropAspectRatio
}
ctx.canvas.width = Math.floor(resizedCropWidth)
ctx.canvas.height = Math.floor(resizedCropHeight)
ctx.scale(pixelRatio, pixelRatio)
ctx.imageSmoothingQuality = 'high'
const cropX = crop.x * scaleX
const cropY = crop.y * scaleY
ctx.save()
ctx.drawImage(
image,
cropX,
cropY,
cropWidth,
cropHeight, // Source crop area in the image
0,
0,
resizedCropWidth,
resizedCropHeight // Destination on the canvas
)
ctx.restore()
}
from react-image-crop.
I've run into this same issue for mobile users on Safari with the preview canvas toBlob method failing to return a blob. It had been working well for months, but on January 10 we started receiving bug reports, all from users on mobile Safari browser and iOS version >17.0.
The behavior I've seen is like in @tylerjbainbridge's screenshot above, where the preview canvas does not populate with an image when the image is first selected. This seems to be happening more often with larger images.
Thanks for looking into this issue, we're also keen to know if anyone's found a work around or a source of the issue.
from react-image-crop.
Are you able to replicate the issue? There was a "Canvas lost" error regression in iOS 17 that was fixed in a patch, wondering if you are able to see what error is in the console
from react-image-crop.
Thanks for looking into this issue, we're also keen to know if anyone's found a work around or a source of the issue.
I just experienced a similar error now. I can create an issue for this if needed.
from react-image-crop.
I found a fix for this 💯
The solution is shown in the image below:
-
when we try to draw canvas on iOS, for downloadable canvas, the pixel ratio
MUST
be 1. if we use the default (the actual device pixelRatio which is 3 or more), the cropping is not going to work because the file will be too big to fit into a blob -
the one in green works on both iOS and android. However, the one in red work for every versions of Android but some versions iOS on mobile are not working.
from react-image-crop.
The exact maximum size of a element depends on the browser and environment. While in most cases the maximum dimensions exceed 10,000 x 10,000 pixels, notably iOS devices limit the canvas size to only 4,096 x 4,096 pixels. See canvas size limits in different browsers and devices.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas#maximum_canvas_size
I'm not sure if devicePixelRatio
affects that you could just make a larger canvas and see.
So the formula is either:
const MAX_SIZE = 4096
or
const MAX_SIZE = 4096 / devicePixelRatio
Then just ensure the crop preview doesn't exceed that (size it down to the max dimensions if exceeded). canvas.drawImage
has params which allow you to resize the image:
dWidth
The width to draw the image in the destination canvas. This allows scaling of the drawn image. If not specified, the image is not scaled in width when drawn. Note that this argument is not included in the 3-argument syntax.
dHeight
The height to draw the image in the destination canvas. This allows scaling of the drawn image. If not specified, the image is not scaled in height when drawn. Note that this argument is not included in the 3-argument syntax.
You can also dynamically determine the max canvas size with that library: https://npmjs.com/package/canvas-size
from react-image-crop.
@sekoyo do you have example of this with the crop logic? I've tried to use the dWidth and dHeight params in your example but to no avail 😢
from react-image-crop.
Just to note on the above example, there is an issue if your user is zoomed in or out, we need to consider this otherwise the crop will be off. This is on my list for next week so I'll update the above if I find a fix 🙇
from react-image-crop.
Related Issues (20)
- Memory leak risk due to event listeners not removed on componentWillUnmount HOT 1
- mask does not fully cover the image when the image to a smaller aspect ratio HOT 2
- Multiple crop selection on an image at the same time HOT 1
- Can the cropper be used for outpainting?
- React Crop as Dialog Box
- The previous image layout still be kept after switch image HOT 1
- Feature request: Add the option to rotate the crop selection
- Proportional Stretching of Crop Box
- iPhone 15's 24 MP (res 4284 X 5712) image resolution is making the image black after cropping. HOT 1
- Library not supporting image cropping in iOS WebView HOT 6
- Add whitespace around image being cropped?
- Cropped area not accounting for zoom of containing elements properly HOT 6
- Deprecation Warnings with SASS 1.77.7 HOT 2
- Maximum Scale Out to produce only complete image without any transparent parts added to result HOT 4
- reload saved cropped image, onComplete returning incorrect crop, but percentCrop is correct.
- Height styling not working with percentages
- While trying to rotate the image, the image itself is not fitting inside the container, full image is not visible after rotating to 90 or 270 degree HOT 4
- expand image to fit container HOT 1
- Problems when importing from react image crop using moduleResolution: "nodenext" in tsconfig.json HOT 2
- when load a cropped image, there is a strange crop range projection on the image HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-image-crop.