web-dev-qa-db-fra.com

Mise à l'échelle d'une image pour l'adapter à la toile

J'ai un formulaire qui permet à un utilisateur de télécharger une image.

Une fois l'image chargée, nous la modifions afin de réduire sa taille avant de la transmettre au serveur.

Pour ce faire, nous le plaçons sur la toile et le manipulons là.

Ce code rendra l'image mise à l'échelle sur la toile, avec la toile de taille 320 x 240px:

ctx.drawImage(img, 0, 0, canvas.width, canvas.height)

... où canvas.width et canvas.height sont la hauteur et la largeur de l'image x un facteur de mise à l'échelle basé sur la taille de l'image d'origine.

Mais quand je vais utiliser le code:

ctx.drawImage(img, 0, 0, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height

... Je ne reçois qu'une partie de l'image sur la toile, dans ce cas le coin supérieur gauche. J'ai besoin que toute l'image soit "ajustée" pour tenir sur la toile, malgré le fait que la taille réelle de l'image soit supérieure à celle de la toile 320x240.

Donc, pour le code ci-dessus, la largeur et les hauteurs sont 1142x856, car il s’agit de la taille finale de l’image. Je dois conserver cette taille pour transmettre le message au serveur lors de la soumission du formulaire, mais je souhaite seulement qu'une plus petite vue apparaisse dans le canevas de l'utilisateur.

Qu'est-ce que j'oublie ici? Quelqu'un peut-il me diriger dans la bonne direction s'il vous plaît?

Merci d'avance.

65
dradd

Indiquez la taille de l'image source (img) en tant que premier rectangle:

ctx.drawImage(img, 0, 0, img.width,    img.height,     // source rectangle
                   0, 0, canvas.width, canvas.height); // destination rectangle

Le deuxième rectangle sera la taille de la destination (quel rectangle source sera redimensionné).

Mise à jour 2016/6 : Pour le rapport de format et le positionnement (à la méthode CSS "" cover "), consultez:
Taille de l'arrière-plan de la simulation: couverture dans la zone de travail

100
user1693593

Vous avez fait l'erreur, lors du deuxième appel, de définir la taille de la source sur la taille de la cible.
Quoi qu’il en soit, je parie que vous voulez le même rapport de format pour l’image redimensionnée, vous devez donc le calculer:

var hRatio = canvas.width / img.width    ;
var vRatio = canvas.height / img.height  ;
var ratio  = Math.min ( hRatio, vRatio );
ctx.drawImage(img, 0,0, img.width, img.height, 0,0,img.width*ratio, img.height*ratio);

je suppose aussi que vous voulez centrer l'image, donc le code serait:

function drawImageScaled(img, ctx) {
   var canvas = ctx.canvas ;
   var hRatio = canvas.width  / img.width    ;
   var vRatio =  canvas.height / img.height  ;
   var ratio  = Math.min ( hRatio, vRatio );
   var centerShift_x = ( canvas.width - img.width*ratio ) / 2;
   var centerShift_y = ( canvas.height - img.height*ratio ) / 2;  
   ctx.clearRect(0,0,canvas.width, canvas.height);
   ctx.drawImage(img, 0,0, img.width, img.height,
                      centerShift_x,centerShift_y,img.width*ratio, img.height*ratio);  
}

vous pouvez le voir dans un jsbin ici: http://jsbin.com/funewofu/1/edit?js,output

117
GameAlchemist