/* * JavaScript Load Image iOS scaling fixes 1.0 * https://github.com/blueimp/JavaScript-Load-Image * * Copyright 2013, Sebastian Tschan * https://blueimp.net * * iOS image scaling fixes based on * https://github.com/stomita/ios-imagefile-megapixel * * Licensed under the MIT license: * http://www.opensource.org/licenses/MIT */ /*jslint nomen: true, bitwise: true */ /*global define, window, document */ (function (factory) { 'use strict'; if (typeof define === 'function' && define.amd) { // Register as an anonymous AMD module: define(['load-image'], factory); } else { // Browser globals: factory(window.loadImage); } }(function (loadImage) { 'use strict'; // Only apply fixes on the iOS platform: if (!window.navigator || !window.navigator.platform || !(/iP(hone|od|ad)/).test(window.navigator.platform)) { return; } var originalRenderMethod = loadImage.renderImageToCanvas; // Detects subsampling in JPEG images: loadImage.detectSubsampling = function (img) { var canvas, context; if (img.width * img.height > 1024 * 1024) { // only consider mexapixel images canvas = document.createElement('canvas'); canvas.width = canvas.height = 1; context = canvas.getContext('2d'); context.drawImage(img, -img.width + 1, 0); // subsampled image becomes half smaller in rendering size. // check alpha channel value to confirm image is covering edge pixel or not. // if alpha value is 0 image is not covering, hence subsampled. return context.getImageData(0, 0, 1, 1).data[3] === 0; } return false; }; // Detects vertical squash in JPEG images: loadImage.detectVerticalSquash = function (img, correctedHeight) { var canvas = document.createElement('canvas'), context = canvas.getContext('2d'), data, sy, ey, py, alpha; canvas.width = 1; canvas.height = correctedHeight; context.drawImage(img, 0, 0); data = context.getImageData(0, 0, 1, correctedHeight).data; // search image edge pixel position in case it is squashed vertically: sy = 0; ey = correctedHeight; py = correctedHeight; while (py > sy) { alpha = data[(py - 1) * 4 + 3]; if (alpha === 0) { ey = py; } else { sy = py; } py = (ey + sy) >> 1; } return (py / correctedHeight) || 1; }; // Renders image to canvas while working around iOS image scaling bugs: // https://github.com/blueimp/JavaScript-Load-Image/issues/13 loadImage.renderImageToCanvas = function ( canvas, img, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight ) { if (img._type === 'image/jpeg') { var context = canvas.getContext('2d'), tmpCanvas = document.createElement('canvas'), tileSize = 1024, tmpContext = tmpCanvas.getContext('2d'), subSampled, vertSquashRatio, tileX, tileY; tmpCanvas.width = tileSize; tmpCanvas.height = tileSize; context.save(); subSampled = loadImage.detectSubsampling(img); if (subSampled) { sourceWidth /= 2; sourceHeight /= 2; } vertSquashRatio = loadImage.detectVerticalSquash(img, sourceHeight); if (subSampled && vertSquashRatio !== 1) { destWidth = Math.ceil(tileSize * destWidth / sourceWidth); destHeight = Math.ceil( tileSize * destHeight / sourceHeight / vertSquashRatio ); destY = 0; tileY = 0; while (tileY < sourceHeight) { destX = 0; tileX = 0; while (tileX < sourceWidth) { tmpContext.clearRect(0, 0, tileSize, tileSize); tmpContext.drawImage( img, sourceX, sourceY, sourceWidth, sourceHeight, -tileX, -tileY, sourceWidth, sourceHeight ); context.drawImage( tmpCanvas, 0, 0, tileSize, tileSize, destX, destY, destWidth, destHeight ); tileX += tileSize; destX += destWidth; } tileY += tileSize; destY += destHeight; } context.restore(); return canvas; } } return originalRenderMethod( canvas, img, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight ); }; }));