I work with uploading photos, trying to display thumbnails of these photos. To resize photos I use canvas . The problem is that canvas draws smaller photos, although for a photo I set the same dimensions as the canvas itself.
The problem, it seems to me, lies in the very drawing ctx.drawImage(img, 0, 0, width, height); but I don’t know how to win it.


The purpose of these gestures is to facilitate the work of the browser, since users (They are the aunts) will load the pictures directly from the camera, that is, the situation when 500 pieces of pictures with a size of 5k pixels are displayed is a common thing.

 //Готовим шаблон let template = document.getElementById('file-template'); let cTemplate = Handlebars.compile(template.innerHTML); let input = document.getElementById('file-input'); input.onchange = function() { let container = document.getElementById('photos'); let files = this.files; //Перебираем файлы в мультиинпуте for(let i in files) { if(!files.hasOwnProperty(i)) continue; let file = files[i]; if (!file.type.match(/image.*/)) continue; let reader = new FileReader(); //Когда картинка прочиталась reader.onload = function(e) { let img = new Image(); img.src = e.target.result; //Вставляем из шаблона container.insertAdjacentHTML( 'beforeend', cTemplate() ); let canvas = container.querySelector('.file:last-of-type .canvas'); let ctx = canvas.getContext('2d'); let height = 100; //Высота превьюх 100 let width = img.width * height / img.height; //Посчитаем их длину canvas.style['width'] = width + 'px'; //Канвас хотим длиной с картинку ctx.drawImage(img, 0, 0, width, height); //Тут почему-то неправильно отрабатывает }; reader.readAsDataURL(file); } }; 
 #photos { display: flex; margin-top: 20px; } .file { position: relative; margin: 0 5px 5px 0; } .file-delete { position: absolute; top: 0; right: 0; background: #fff; width: 18px; color: #f00; text-align: center; text-decoration: none; } canvas { background: #ccc; width: 0px; height: 100px; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.6/handlebars.min.js"></script> <input id="file-input" type="file" multiple="multiple"> <div id="photos"></div> <script id="file-template" type="text/x-handlebars-template"> <div class="file"> <a href='#' class="file-delete">&times;</a> <canvas class="canvas"></canvas> </div> </script> 

    1 answer 1

     //Готовим шаблон let template = document.getElementById('file-template'); let cTemplate = Handlebars.compile(template.innerHTML); let input = document.getElementById('file-input'); input.onchange = function() { let container = document.getElementById('photos'); let files = this.files; //Перебираем файлы в мультиинпуте for (let i in files) { if (!files.hasOwnProperty(i)) continue; let file = files[i]; if (!file.type.match(/image.*/)) continue; let reader = new FileReader(); //Когда картинка прочиталась reader.onload = function(e) { let img = new Image(); img.src = e.target.result; //Вставляем из шаблона container.insertAdjacentHTML('beforeend', cTemplate()); let canvas = container.querySelector('.file:last-of-type').querySelector('.canvas'); canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; var ctx = canvas.getContext("2d").drawImage(img, 0, 0); canvas.style['width'] = img.naturalWidth / 4 + 'px'; canvas.style['height'] = img.naturalHeight / 4 + 'px'; }; reader.readAsDataURL(file); } }; 
     #photos { display: flex; margin-top: 20px; } .file { position: relative; margin: 0 5px 5px 0; } .file-delete { position: absolute; top: 0; right: 0; background: #fff; width: 18px; color: #f00; text-align: center; text-decoration: none; } canvas { background: #ccc; width: 0px; height: 100px; } 
     <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.6/handlebars.min.js"></script> <input id="file-input" type="file" multiple="multiple"> <div id="photos"></div> <script id="file-template" type="text/x-handlebars-template"> <div class="file"> <a href='#' class="file-delete">&times;</a> <canvas class="canvas"></canvas> </div> </script> 

    • Thank you for your attention, I have a question. Making huge canvases and then shaking them 4 times is not the same thing as making big pictures and shaking them in a version? Now I will slightly correct the question, write my goal, so that it is clearer what worries me - user200141
    • @ user200141 Do you want to shrink the size of the pictures? - C.Raf.T
    • Clarified the question. I'm trying not to bend the browser on weak office computers, displaying previews - user200141
    • @ user200141 I think to start limiting the number of pictures for uploading ...?) - C.Raf.T
    • I think this is not very convenient for the user - user200141