Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Проблема со сжатием изображения (https://javascript.ru/forum/dom-window/60768-problema-so-szhatiem-izobrazheniya.html)

tvixa 19.01.2016 14:17

Проблема со сжатием изображения
 
Добрый вечер, форумчане. У меня возникла проблема, есть drag`n`drop загрузчик изображений. Нужна функция, сжимающая изображение при загрузке до размеров 760*300 px.
Использовала canvas, но что-то не работает, помогите пожалуйста разобраться
в блоке source_image - загружаемое, в блоке result_image полученное.
(уже припилена функция уменьшения размера)

$(function() {
    var output_format = "jpg";
    /** DRAG AND DROP STUFF WITH FILE API **/
    var holder = document.getElementById('holder');
    holder.ondragover = function() {
        this.className = 'is_hover';
        $('#result_image').hide();
        return false;
    };
    holder.ondragend = function() {
        this.className = '';
        return false;
    };
    holder.ondrop = function(e) {
        this.className = '';
        e.preventDefault();
        
        $('#div-img-setup').css('display','block');
        $('#source_image').css('display','block');

        var file = e.dataTransfer.files[0],
        reader = new FileReader();
        var name=file.name;
        reader.onload = function(event) {
            var i = document.getElementById("source_image");
           	var j = document.getElementById("result_image");
            i.src = event.target.result;
            j.src = event.target.result;
            i.onload = function() {
           	 		resize(i);
                function resize(image){
                    var width= 765;
                    var height=300;
                    var imgWidth=image.width;
                    var imgHeight=image.height;
                    var ratioW=width/imgWidth;
                    var ratioH=height/imgHeight;
                    var ratio=Math.min(ratioW,ratioH);
                    width=imgWidth*ratio;
                    height=imgHeight*ratio;
                    width=Math.round(width);
                    height=Math.round(height);
                    var canvas = document.createElement('canvas');
                    canvas.width = width;
                    canvas.height = height;
                    if(imgWidth/2>width && imgHeight/2>height){
                        var canvasTemp = document.createElement('canvas');
                        canvasTemp.width = imgWidth/2;
                        canvasTemp.height = imgHeight/2;
                        canvasTemp.getContext('2d').drawImage(image, 0, 0, imgWidth/2, imgHeight/2);
                        imgWidth=imgWidth/2;
                        imtHeight=imgHeight/2;
                        while(imgWidth/2>width && imgHeight/2>height){
                            var canvas2 = document.createElement('canvas');
                            canvas2.width = imgWidth/2;
                            canvas2.height = imgHeight/2;
                            canvas2.getContext('2d').drawImage(canvasTemp, 0, 0, imgWidth/2, imgHeight/2);
                            imgWidth=imgWidth/2;
                            imtHeight=imgHeight/2;
                            canvasTemp=canvas2;
                        }
                        canvas.getContext('2d').drawImage(canvasTemp, 0, 0, width, height);
                    } else {
                        canvas.getContext('2d').drawImage(image, 0, 0, width, height);
                    }
                }
           	 }
        };
        if(file.type=="image/png"){
            output_format = "png";
        }
        reader.readAsDataURL(file);
        return false;
    };
});

laimas 19.01.2016 15:02

Что-то слишком много написано для изменения разрешения, да и изначально либо неверно условия заданы, либо не договорено что-то. Если изображение должно быть размером 765х300, то исходное изображение обязательно должно быть альбомной ориентации, а отношение его ширины к высоте больше или равно 2.55, при этом высота его должна быть больше или равна 300. Если это не выполняется, значит отказ. Если отношение больше чем 2.55, значит нужно выбирать часть изображения, и тут сложно сказать что будут лучше, взять ли область слева или же центральную часть исходного.

tvixa 19.01.2016 15:30

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

laimas 19.01.2016 15:55

Цитата:

Сообщение от tvixa
изображение должно растягиваться вне зависимости от размеров исходного даже с коверканием.

Ну если даже и в этом есть смысл, то не знаю чего вы там лишнего отрезали, если у вас лишнего даже и при таком условии хоть отбавляй. Забудьте пока об этом коде, напишите отдельно код только увеличения/уменьшения изображения до нужного размера, а он будет (должен быть) совсем простой. А уж потом прикрутите его к перетаскиванию.

Не знаю для чего это потребовалось, но а) canvas использует далеко не лучший метод интерполяции и качество получается довольно таки паршивое, б) если все под один размер и не для сохранения, что трудно представить, то это можно сделать и на CSS.

tvixa 20.01.2016 10:56

Разобралась в чём проблема, действительно было много лишнего кода. Выкладываю, может пригодится.
reader.onload = function(event) {
            var i = document.getElementById("source_image");
           	var j = document.getElementById("result_image");
            img = new Image();
            img.src = event.target.result;
            i.src = event.target.result;
            j.src = event.target.result;
            img.onload = function() {
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                canvas.width=765
                canvas.height=300
                ctx.drawImage(i, 0, 0, 765, 300);

                $("#holder").append(canvas);
                var dataURL = canvas.toDataURL();
                document.getElementById('source_image').src = dataURL;
                document.getElementById('result_image').src = dataURL;
           	 }
        };

laimas 20.01.2016 11:15

Это j.src = event.target.result; зачем?
Да и зачем
img.src = event.target.result;
и
i.src = event.target.result;

Есть источник, рассчитали параметры увеличения/уменьшения (у вас этого не видно и близко, если конечно наплевать на искажения), с этими параметрами берем из исходного в canvas. Зачем плодить лишнее.


Часовой пояс GMT +3, время: 23:32.