Como escalar imagens em uma tela html5 com melhor interpolação?

Primeiro de tudo: o que estou tentando fazer?

Eu tenho um aplicativo para visualizar imagens. Ele usa o elemento canvas para renderizar a imagem. Você pode aumentar o zoom, diminuir o zoom e arrastá-lo. Esta parte funciona perfeitamente agora.

Mas digamos que eu tenha uma imagem com muito texto. Tem uma resolução de 1200x1700 e a minha tela tem 1200x900. Inicialmente, quando diminuído, isso leva a uma resolução renderizada de ~ 560x800.

Meu desenho real é assim:

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

O texto pequeno nesta imagem parece muito, muito ruim, especialmente quando comparado a outros visualizadores de imagens (por exemplo, IrfanView), ou mesmo ao elemento html <img>.

Eu descobri que o algoritmo de interpolação dos navegadores é a causa desse problema. A comparação de diferentes navegadores mostrou que o Google Chrome torna as imagens dimensionadas melhor, mas ainda não é bom o suficiente.

Bem, eu procurei em todos os cantos da Interwebs por 4-5 horas seguidas e não encontrei o que eu preciso. Eu encontrei a opção "imageSmoothingEnabled", os estilos CSS "image-rendering" que você não pode usar em canvas, renderizando em posições flutuantes e muitas implementações em JavaScript de algoritmos de interpolação (estes sãolonge para retardar para o meu propósito).

Você pode perguntar por que eu estou lhe dizendo tudo isso: para economizar tempo para me dar respostas que eu já sei

Então: existequalquer maneira boa e rápida de ter melhor interpolação? Minha idéia atual é criar um objeto de imagem, redimensionar isso (porque img tem boa interpolação quando dimensionado!) E processá-lo então. Infelizmente, aplicar img.width parece afetar apenas a largura exibida ...

Atualizar: Graças ao Simon, eu poderia resolver o meu problema. Aqui está o algoritmo de escala dinâmica que usei. Observe que ele mantém a proporção, o parâmetro height é apenas para evitar mais computação float. Ele só diminui agora.

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);
    }

questionAnswers(1)

yourAnswerToTheQuestion