Как масштабировать изображения на холсте html5 с лучшей интерполяцией?

Прежде всего: что я пытаюсь сделать?

У меня есть приложение для просмотра изображений. Он использует элемент canvas для визуализации изображения. Вы можете увеличить, вы можете уменьшить масштаб, и вы можете перетащить его. Эта часть отлично работает прямо сейчас.

Но скажем, у меня есть изображение с большим количеством текста. У него разрешение 1200х1700, а у моего холста 1200х900. Первоначально при уменьшении это приводит к разрешению ~ 560x800.

Мой фактический рисунок выглядит так:

drawImage(src, srcOffsetX, srcOffsetY, sourceViewWidth, sourceViewHeight,
destOffsetX, destOffsetY, destWidth, destHeight);

Небольшой текст на этом изображении выглядит очень-очень плохо, особенно по сравнению с другими программами просмотра изображений (например, IrfanView) или даже элементом html <img>.

Я понял, что причиной этой проблемы является алгоритм интерполяции браузеров. Сравнение различных браузеров показало, что Chrome отображает масштабированные изображения лучше, но все еще недостаточно хорош.

Ну, я искал в каждом углу Interwebs в течение 4-5 часов подряд и не нашел то, что мне нужно. Я нашел опцию «imageSmoothingEnabled», стили CSS «рендеринг изображений», которые вы не можете использовать на холсте, рендеринг в плавающих позициях и многие реализации JavaScript алгоритмов интерполяции (далеко&nbsp;чтобы замедлить для моей цели).

Вы можете спросить, почему я говорю вам все это: чтобы сэкономить время, чтобы дать мне ответы, которые я уже знаю

Итак: есть лиЛюбые&nbsp;хороший и быстрый способ иметь лучшую интерполяцию? Моя текущая идея - создать объект изображения, изменить его размер (потому что img имеет хорошую интерполяцию при масштабировании!) И затем отобразить его. К сожалению, применение img.width влияет только на отображаемую ширину ...

ОбновитьСпасибо Саймону, я смог решить мою проблему. Вот алгоритм динамического масштабирования, который я использовал. Обратите внимание, что он сохраняет соотношение сторон, параметр высоты предназначен только для избежания дополнительных вычислений с плавающей точкой. Это только уменьшится прямо сейчас.

scale(destWidth, destHeight){
        var start = new Date().getTime();
        var scalingSteps = 0;
        var ctx = this._sourceImageCanvasContext;
        var curWidth = this._sourceImageWidth;
        var curHeight = this._sourceImageHeight;

        var lastWidth = this._sourceImageWidth;
        var lastHeight = this._sourceImageHeight;

        var end = false;
        var scale=0.75;
        while(end==false){
            scalingSteps +=1;
            curWidth *= scale;
            curHeight *= scale;
            if(curWidth < destWidth){
                curWidth = destWidth;
                curHeight = destHeight;
                end=true;
            }
            ctx.drawImage(this._sourceImageCanvas, 0, 0, Math.round(lastWidth), Math.round(lastHeight), 0, 0, Math.round(curWidth), Math.round(curHeight));
            lastWidth = curWidth;
            lastHeight = curHeight;
        }
        var endTime =new Date().getTime();
        console.log("execution time: "+ ( endTime - start) + "ms. scale per frame: "+scale+ " scaling step count: "+scalingSteps);
    }