Сортировать по разрешению изображения в галерее

Я сделал эту галерею некоторое время назад: https://jsfiddle.net/5e9L09Ly/

Не беспокойтесь, он ничего не загрузит.

Я сделал, что вы можете сортировать по размеру файла, но я хочу сортировать по разрешению изображения. Проблема в том, что не все изображения будут загружены на страницу, но я не буду знать, каков их размер.

Сама галерея довольно простая, она запрашивает каталог и затем отображает все изображения и видео в этом каталоге.

Он работает только в хроме прямо сейчас, просто нажмите на просмотр на самом верху. Число перед просмотром – сколько изображений должно отображаться или загружаться при выборе каталога.

Я не уверен, как подойти к этой проблеме …

Одна вещь, которую я имел в виду, была примерно такая:

imgLoad.attr("src", url); imgLoad.unbind("load"); imgLoad.bind("load", function() { console.log(url+' size: '+(this.width + this.height)); }); 

Проблема с этим заключается в том, что он загружает каждое изображение, которое он загружает, и это сильно повлияет на hdd и browser, если у вас много изображений, скажем, 20k изображений, которые вы пытаетесь загрузить.

Так что да … любые предложения были бы замечательными.

Я не буду публиковать код здесь, потому что это слишком много, пожалуйста, проверьте скрипку.

Теоретически, можно было бы немного задействовать обработку браузера, извлекая эти значения из представлений uploadB файлов из массива.

В большинстве форматов изображений есть читаемые метаданные, содержащие размеры носителя, поэтому мы можем получить к нему доступ, не прося браузер фактически анализировать и вычислять данные изображения (распаковывать, декодировать и т. Д.).

Вот действительно грубое доказательство концепции, используя ExifReader lib, что я не слишком много тестировал , для jpeg-изображений.

 /* Rough proof of concept of getting image files width & height by reading their metadata directly in arrayBuffer, instead of loading it Should support most jpeg png gif and bmp image files (though all versions of these formats have NOT been tested) @input A fileList. @output A promise whose fulfillment handler receives an Array containing successfully parsed files. */ function getImageSizes(files) { /* Attaches a buffer of the size specified to the File object */ function getBuffer(fileList, size) { return new Promise((resolve, reject) => { const fr = new FileReader(); const toLoad = fileList.length; if (!toLoad) { // an empty list resolve(fileList); return; } let arr = []; let loaded = 0; let current = fileList[loaded]; let chunk = current.slice(0, size || current.size); // get only the required bytes fr.onload = e => { fileList[loaded].buf = fr.result; if (++loaded < toLoad) { current = fileList[loaded]; chunk = current.slice(0, size || current.size); fr.readAsArrayBuffer(chunk); } else { // once all the list has been treated resolve(fileList); } }; fr.readAsArrayBuffer(chunk); }); } /* png is easy, IHDR starts at 16b, and 8 first bytes are 32bit width & height */ // You can read https://www.w3.org/TR/PNG-Chunks.html for more info on each numeric value function getPNGSizes(pngArray) { let view; // Little endian only function readInt16(offset) { return view[offset] << 24 | view[offset + 1] << 16 | view[offset + 2] << 8 | view[offset + 3]; } pngArray.forEach(o => { view = new Uint8Array(o.buf); o.meta = { width: readInt16(16), height: readInt16(20), bitDepth: view[24], colorType: view[25], compressionMethod: view[26], filterMethod: view[27], interlaceMethod: view[28] }; o.width = o.meta.width; o.height = o.meta.height; }); return pngArray; } function getJPEGSizes(jpegArray) { /* the EXIF library seems to have some difficulties */ let failed = []; let retry = []; let success = []; // EXIF data can be anywhere in the file, so we need to get the full arrayBuffer return getBuffer(jpegArray).then(jpegArray => { jpegArray.forEach(o => { try { const tags = ExifReader.load(o.buf); if (!tags || !tags.PixelXDimension) { throw 'no EXIF'; } o.meta = tags; // since OP said he wanted it o.width = tags.PixelXDimension.value; o.height = tags.PixelYDimension.value; success.push(o); } catch (e) { failed.push(o); return; } }); // if some have failed, we will retry with the ol'good img way retry = failed.map((o) => { return new Promise((resolve, reject) => { let img = new Image(); img.onload = e => { URL.revokeObjectURL(img.src); o.width = img.width; o.height = img.height; resolve(o); }; img.onerror = e => { URL.revokeObjectURL(img.src); reject(o); }; img.src = URL.createObjectURL(o); }); }); return Promise.all(retry) // concatenate the no-exif ones with the exif ones. .then(arr => success.concat(arr)) }); } function getGIFSizes(gifArray) { gifArray.forEach(o => { let view = new Uint8Array(o.buf); o.width = view[6] | view[7] < < 8; o.height = view[8] | view[9] << 8; }); return gifArray; } function getBMPSizes(bmpArray) { let view; function readInt(offset) { // I probably have something wrong in here... return Math.abs(view[offset] | view[offset + 1] << 8 | view[offset + 2] << 16 | view[offset + 3] << 24 ); } bmpArray.forEach(o => { view = new Uint8Array(o.buf); o.meta = { width: readInt(18), height: readInt(22) } o.width = o.meta.width; o.height = o.meta.height; }); return bmpArray; } // only based on MIME-type string, to avoid all non-images function simpleImageFilter(files) { return Promise.resolve( Array.prototype.filter.call(files, f => f.type.indexOf('image/') === 0) ); } function filterType(list, requestedType) { // A more robust MIME-type check // see http://stackoverflow.com/questions/18299806/how-to-check-file-mime-type-with-javascript-before-upload function getHeader(buf) { let type = 'unknown'; let header = Array.prototype.map.call( new Uint8Array(buf.slice(0, 4)), v => v.toString(16) ).join('') switch (header) { case "89504e47": case "0D0A1A0A": type = "image/png"; break; case "47494638": type = "image/gif"; break; case "ffd8ffe0": case "ffd8ffe1": case "ffd8ffe2": type = "image/jpeg"; break; default: switch (header.substr(0, 4)) { case "424d": type = 'image/bmp'; break; } break; } return type; } return Array.prototype.filter.call( list, o => getHeader(o.buf) === requestedType ); } function getSizes(fileArray) { return getJPEGSizes(filterType(fileArray, 'image/jpeg')) .then(jpegs => { let pngs = getPNGSizes(filterType(fileArray, 'image/png')); let gifs = getGIFSizes(filterType(fileArray, 'image/gif')); let bmps = getBMPSizes(filterType(fileArray, 'image/bmp')); return gifs.concat(pngs.concat(bmps.concat(jpegs))); }); } return simpleImageFilter(files) .then(images => getBuffer(images, 30)) .then(getSizes); } // our callback function sort(arr) { arr.sort(function(a, b) { return a.width * a.height - b.width * b.height; }); output.innerHTML = ''; arr.forEach(f => { // ugly table generation let t = '', tt = '' + t, ttt = ''; output.innerHTML += '' + t + f.name + tt + f.width + tt + f.height + ttt; }) } f.onchange = e => { getImageSizes(f.files) .then(sort) .catch(e => console.log(e)); output.innerHTML = 'Processing, please wait...'; } 
 table { margin-top: 12px; border-collapse: collapse; } td, th { border: 1px solid #000; padding: 2px 6px; } tr { border: 0; margin: 0; } 
   
file name width height
Please choose a folder to upload

вы можете получить размер изображения, используя это после сортировки в соответствии с вашим требованием

это мой пример: как получить размер изображения перед загрузкой https://jsfiddle.net/mmghori/Lsnc0sr7/

а также

здесь вы обновили скрипт https://jsfiddle.net/mmghori/ubgLv3cb/ , в этой скрипке я добавляю свой код и размер изображения консоли,

поэтому я просто нахожу, как получить размер изображения перед загрузкой.

  

var _URL = window.URL || window.webkitURL; $("#file").change(function(e) { var file, img; if ((file = this.files[0])) { img = new Image(); img.onload = function() { $("#fileSize").text(this.width + "x" + this.height); }; img.onerror = function() { alert( "not a valid file: " + file.type); }; img.src = _URL.createObjectURL(file); } });

Вы должны обрабатывать изображения партиями, скажем, по 20 за раз.

При загрузке изображения вы сохраняете имя и разрешение для каждого изображения в массиве, а затем уничтожаете изображения для освобождения памяти

Когда вы получаете 20 onload или onerror, вы обрабатываете следующую партию.

Когда все будет сделано, вы отсортируете массив и отобразите изображения.

Если их сотни или тысячи, вам нужно разбивать галерею на галерею

Это должно быть просто, поскольку у вас уже есть массив со всеми именами изображений и разрешениями под рукой.

просто установите некоторые переменные для начала смещения и размера страницы и slice () массив, чтобы получить нужное подмножество («текущая страница»)

Сама галерея довольно простая, она запрашивает каталог и затем отображает все изображения и видео в этом каталоге.

Вот простое решение, как получить размер всех изображений на веб-странице, поэтому, если у вас есть что-то вроде простой фотогалереи, то, что получается из папки, и у вас нет списка этих изображений, это самое простое решение, как получите размер этого, а затем вы сможете обрабатывать, как вы хотите.

 for( i=0; i < document.images.length; i++) { width = document.images[i].width; height = document.images[i].height; console.log("Image number: " + i + " Size: " + width + "x" + height); } 
 < !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">   Get image size example       

Может ли что-то подобное помочь?

 var imgs = document.getElementsByClassName("imgs"); var height = imgs.clientHeight; var width = imgs.clientWidth; imgs.sort(function(a, b){ return a.height - b.width; }); 

или используя node.js:

 imgs.sort(function(a, b) { return fs.statSync(a).size - fs.statSync(b).size; });