Explain Codes LogoExplain Codes Logo

Html5 Pre-resize images before uploading

html
responsive-design
image-processing
ajax
Nikita BarsukovbyNikita BarsukovΒ·Nov 17, 2024
⚑TLDR

Use HTML5's powerful APIs, specifically FileReader and <canvas>, to resize images before upload. The process involves reading the image as a data URL, rendering it on a canvas, scaling down with respect to the aspect ratio, and finally converting it back to a blob for upload. Here is a practical example:

function resizeImage(file, maxWidth, maxHeight, callback) { let reader = new FileReader(); reader.onload = e => { let img = new Image(); img.onload = () => { let canvas = document.createElement('canvas'); // the magic happens here! 🎩 let scale = Math.min(maxWidth / img.width, maxHeight / img.height); canvas.width = img.width * scale; canvas.height = img.height * scale; let ctx = canvas.getContext('2d'); // fetches the 2D rendering context for the drawing surface of a `<canvas>` // let the Picasso in you do the work πŸ–ŒοΈ ctx.drawImage(img, 0, 0, canvas.width, canvas.height); canvas.toBlob(callback, 'image/jpeg', 0.9); // cheers JPEG! 🍻 }; img.src = e.target.result; }; reader.readAsDataURL(file); // savors the data URL like a fine wine 🍷 }; // Use case document.querySelector('input[type=file]').onchange = e => { const maxWidth = 800; // maximum width setting (our measuring stick) πŸ“ const maxHeight = 600; // maximum height setting (another measuring stick) πŸ“ resizeImage(e.target.files[0], maxWidth, maxHeight, resizedBlob => { // resizedBlob ready for upload. πŸš€ }); };

This script safeguards image quality and aspect ratio simultaneously optimizes for superior performance by running the process client-side.

Handling a slew of image types and quality parameters

Real-life scenarios demand the handling of various image formats and different quality considerations:

  • Multi-format Support: Besides the classic JPEG, support for PNG, GIF, and WebP might come in handy. Simply employ canvas.toBlob(callback, 'image/png') for PNG and similarly for others.
  • Quality Spectrum: The third constituent of canvas.toBlob(), which has a range from 0 (lowest) to 1 (highest) denotes the JPEG image quality. Attempt to find the perfect middle ground between image size and presentation quality.

Automating aspect ratio computation for consistent resizing

Aspect ratios can turn out to be a bit tricky. Maintain the original image proportion by:

const aspectRatio = img.width / img.height; canvas.height = maxHeight; canvas.width = canvas.height * aspectRatio; if (canvas.width > maxWidth) { canvas.width = maxWidth; canvas.height = canvas.width / aspectRatio; }

Efficient procedures for massive file input

With large files or multiple files, memory usage and main thread responsiveness become key considerations. Consider:

  • Queuing: Dispose of images one after another or in small groups.
  • Web Workers: Delegate the resizing task to background threads using Web Workers, saving the main thread from becoming unresponsive.

Uploading with a steadfast AJAX method sans page refresh

AJAX offers a flawless experience when transmitting the image data to the server:

const xhr = new XMLHttpRequest(); xhr.open('POST', 'your_server_endpoint', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send(`imageData=${encodeURIComponent(resizedBlob)}`);

Remember to set processData: false, to prevent jQuery from converting the blob into a string, preserving the image data's binary integrity.

Highlighting potential hiccups

Stay on the lookout for:

  • Memory Leaks: Clear large variables or blob objects to prevent memory bloat after use.
  • Browser Support: Cross-check support for FileReader, <canvas>, and toBlob methods, especially with older browsers.
  • File Size Limits: Account for server upload limits while deciding max dimensions and quality settings.