Building a upload profile picture system.
Looking for a system to allow square images and allow user to select small part of large image (means need cropping). Also validate based on size and dimensions as per needs.
Client side cropping
HTML5 canvas and localstorage based solutions are present like ngImgCrop, Angular Image Crop, but there are problems like -
image distorts if high resultion (more than 1 MB)
may be not supported in some old (non-html5) browsers
Server side cropping
Solutions like Jcrop but long workflow and time/bandwidth consuming.
client needs to send full large file to server even if its 5MB
then download it again from server to preview
then show crop UI and send crop co-ordinates
server performs cropping and creates file
cropped image is downloaded and displayed
What will be the best approach. Tell me more pros and cons of each. What should a great startup do and what is the industry standard solution as of now and why?
The best answer to this mainly depends on your target audience. Many people who are used to using online services will have a pre-cropped or small version of their profile image ready to upload, and will know not to try to upload a 20 mega-pixel photo. If your target audience is more traditional, then you will probably want to shift your approach to be more forgiving and focussed on older, widely supported technologies.
For me, the best solution is the following:
Focus on a client-side solution - have the user crop the photo on the client side, then optimise it on the server.
To counter the massive photo image, either have a simple label "max file size: 1mb", or check the file size when they initially select the photo, and upload & resize/compress it first.
What should a great startup do and what is the industry standard solution as of now and why?
A great startup should not be restricted or over-influenced by industry standards and should reason through the various approaches themselves.
Related
My use case involves uploading thousands of full quality photo and video files using browser to S3 and Wasabi storage accounts. Currently we are compression it on client's browser and right now we did it using dropzonejs which handles uploading. Right now its compressed before being uploaded to server.
However, that's what we need to change. We need to upload original quality photos and that's where it gets stuck as we cannot upload files more than 3-4 Gbs using Dropzonejs. Not sure what prevents it but we are struggling to find solution for this. We face problem randomly with memory limit in Chrome which crashes and need to restart process again. With original quality photo we assume this would not work as we will be talking for at least 10 to 15 gbs of data at least.
What would you recommend for this kind of use case where we need to upload video & photos in original quality sometimes a single photo could be taking as much as 40Mbs+. And video several Gbs.
How does Google photos manages this? We need something like that.
Chunking...
someone already have demo
https://github.com/dropzone/dropzone/blob/main/test/test-sites/2-integrations/aws-s3-multipart.html
but, i think 4GB is the max file size that Chrome will accept(And I think chrome has the highest limit compare to other browsers). which means you need to use other method to upload such as ftp, stream, scp etc... or ask your clients to slice the files themselves before uploading through their browser.
Or create a custom executable that bundles with S3 client, and let your clients use that
Do not compress on client side. It actually increases memory usage on the browser session. To my experience uploading original image from the browser uses least amount of memory as the browser should only read enough from the file to send the data, as long as you're not loading the picture locally to show the thumbnails.
I was able to upload GBs of images to S3 with client side compression turned off. I was able to upload a single 20GB video file to S3, upload 200 videos totaling over 13GB using S3 Chunk upload. Chunk upload should increase, not decrease browser memory usage and was implemented to hand transmission failures for large files.
dropzonejs supports chunking and paralleling
did you use them?
do you compress files by dropzone like this:
https://stackoverflow.com/a/51699311/18399373
You can have a huge performance improvement by writing your client to upload directly to S3 by providing a signed url(s) and have them skip the server as the middle man:
S3:
https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html
GCP:
https://cloud.google.com/blog/products/storage-data-transfer/uploading-images-directly-to-cloud-storage-by-using-signed-url
I would recommend using presigned url from S3. In our Project we generate presigned url by giving bucket name, path name, bucket access to upload and expiry time. So now the user can upload the file easily directly to S3. AWS will take care of all the networking issues, only condition is you should have a good internet.
I have a basic defense on the client (React.js) to check for the file and size. That provides small security as the yser can change the extension and upload any file type on the server.
I did this type of checking previously using Image Magick on the Express.js project, and that worked very nicely.
This time, I do not need all of the weapons Image magick providesm just need to make sure that the file is indeed an image. Is there an alternative?
If not, than I will end up using IM, but really would be nice to have some small sized library that just does this.
Context:
I setup a photo upload that uses an iframe to upload the image, then that has an optional jCrop step.
the client doesn't want to have to wait for the image to be uploaded. here's what the client said:
"You shouldn't have to wait for anything on the server end.
I don't care if the cropping happens on the server or client.
The interaction for cropping shouldn't wait on upload"
Is the client crazy, or is there some kind of way for me to have the image available for front-end manipulation instantly?
Edit:
TLDR: using a <input type="file"/>, if a user picks an image, can I immediately reference that local file somehow? would that show up as the input's value after change?
I can think of three technics to do a browser based image manipulation possible:
- java applet
- flash
- html5: file api (to read the image) and canvas (to show and manipulate it). But the browser support for the file api is not quite good as far as I know.
I am using the HTML5 File API to upload the file to server.
It offers following amazing things,
Upload object which support the progress event which make it possible to show nice progress UI to end user.
XHR.send(File) and XHR.send(FormData) can carry big files(decent sized off course ) across the wire with no need to load entirely in memory.
input type="file" with multiple
option.
Drag Drop from desktop in Firefox and Chrome.
All looks promising and good however still considering its our good old HTTP which is there and unpredictable network. I would like to know if HTML5 is still really going to change file upload experience beyond UI progress and all. Or it will be same HTTP 2GB max request size (ASP.NET) and bandwidth restrictions. Will it allow big file sizes.
HTML5 (or any other mark-up language) won't and can't change any server-side rules or bypass any bandwidth restrictions.
Is there any Jquery Plugin to perform the image dimension operation on an image before being uploaded using uplodify. i want the plugin to check the image dimension with the fixed define size and then only process for uploading.
right now i am doing it with PHP function, instead of server side validation i want to adopt the client side validation.
I do not believe that this is possible, since JavaScript is not allowed to access the local filesystem (for security reasons).
Have you considered any other alternatives?
I have similar problem as you do, though i am using asp.net C#
this is my solution:
of course, obvious user guidance of the image uploading control
use server end image thumbnail
facility, automatically resize the
image into the right size that your
system required.
display result preview for user
doing final review after upload.
it is ideal to check in client end first, however JS may causing compatibility issue.
secondly, always check on server end, since client end is not always reliable.