Comment redimensionner des images sur un html5 canvas avec une meilleure interpolation?
Tout d'abord: que suis-je en train de faire?
J'ai une application pour l'affichage des images. Il utilise l'élément canvas pour le rendu de l'image. Vous pouvez effectuer un zoom avant, vous pouvez effectuer un zoom arrière, et vous pouvez le déplacer. Cette partie fonctionne parfaitement maintenant.
Mais disons que j'ai une image avec beaucoup de texte. Il dispose d'une résolution de 1200x1700, et ma toile a 1200x900. Initialement, lors d'un zoom arrière, ce qui conduit à une résolution de ~560x800.
Mon dessin ressemble à ceci:
drawImage(src, srcOffsetX, srcOffsetY, sourceViewWidth, sourceViewHeight,
destOffsetX, destOffsetY, destWidth, destHeight);
Un petit texte sur cette image semble vraiment, vraiment mauvais, surtout quand on le compare à d'autres visionneuses d'images (par exemple, IrfanView), ou même html < img > élément.
J'ai compris que les navigateurs algorithme d'interpolation est la cause de ce problème. En comparant les différents navigateurs ont montré que le Chrome rend échelle images du mieux, mais pas encore assez.
Bien j'ai cherché dans tous les coins de la Interwebs pendant 4 à 5 heures d'affilée et ne pas trouver ce dont j'ai besoin. J'ai trouvé le "imageSmoothingEnabled" option "image-rendu de" styles CSS qui vous ne pouvez pas l'utiliser sur toile, rendu à flotteur de positions et de nombreux JavaScript implémentations des algorithmes d'interpolation (ceux qui sont loin à ralentir pour mon usage).
Vous pouvez vous demander pourquoi je vous raconte tout cela: pour vous faire gagner du temps à me donner des réponses, je sais déjà
Donc: est-il tout bon et rapide façon d'avoir une meilleure interpolation? Mon idée est de créer un objet image, redimensionner ce (parce img a une bonne interpolation lors de l'échelle!) et le rendre ensuite. Malheureusement, l'application de img.la largeur ne semble affecter la largeur d'affichage...
Mise à jour: Merci à Simon, j'ai pu résoudre mon problème.
Voici la dynamique de mise à l'échelle de l'algorithme que j'ai utilisé. Avis de conserver les proportions, la hauteur paramètre est uniquement pour éviter plus de flotteur de l'informatique. Il ne échelles en bas à droite maintenant.
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);
}
- Par "une meilleure interpolation" vous voulez dire une interpolation dédié à une meilleure lisibilité du texte à l'échelle ?
- une meilleure interpolation en général. la mauvaise qualité du texte est juste la chose la plus remarquable à vous de voir... et de la lisibilité du texte est, malheureusement, très important pour ce projet. mais si vous connaissez un moyen uniquement de rendre le texte plus agréable à regarder, s'il vous plaît dites-moi alors!
- double possible de Html5 canvas drawImage: comment appliquer l'anticrénelage
- étrange. je n'ai pas trouvé la page en question, en dépit de la recherche depuis si longtemps..
- Vous pouvez essayez d'incorporer le texte au format HTML dans un foreignObject à l'intérieur de SVG que vous pouvez ensuite rendu à la toile. J'ai l'habitude de faire beaucoup mieux le rendu du texte et de cette façon, puis forme le canevas des méthodes directement.
Vous devez vous connecter pour publier un commentaire.
Vous avez besoin de "descendre" à plusieurs reprises. Au lieu de mise à l'échelle à partir d'une très grande image à un très petit, vous avez besoin de re-dimensionner à intermédiaire tailles.
Considérer une image que vous voulez dessiner à l'échelle 1/6. Vous pouvez faire ceci:
Ou vous pouvez dessiner en mémoire une toile à l'échelle 1/2, puis 1/2 échelle de nouveau, puis 1/2 balance. Le résultat est un 1/6 scale image, mais nous utilisons trois étapes:
Alors vous pouvez tirer en arrière à l'original de votre contexte:
Vous pouvez voir la différence vivre, ici:
JS:
CSS:
HTML:
Vue même extrait sur jsfiddle.
drawImage()
est l'un des plus rapides les opérations que vous pouvez faire sur la toile, afin de ne pas se sentir mal à propos 8x étape de valeur sur l'image échelles