Question

Par exemple, si j'ai besoin de remplir un cadre de sélection de 100 pixels de large sur 50 pixels de haut, les images d'entrée suivantes auront le comportement suivant:

  1. 200w x 200h est réduit de 50% et 25% sont hachés au sommet et en bas.

  2. 200w x 100h est réduit à 50% sans recadrage.

  3. 100w x 200h obtient n'est pas mis à l'échelle, mais 75px coupés en haut et en bas.

Cela semble être une fonction de redimensionnement courante, mais je n'ai pas réussi à trouver un exemple de l'algorithme.

Acceptera les réponses dans toutes les langues, y compris le pseudo-code. Un lien vers une page avec la réponse est très bien aussi!

Était-ce utile?

La solution

Ce que vous demandez est assez facile. Calculez les différents facteurs de mise à l'échelle pour la largeur et la hauteur, puis choisissez le plus grand pour votre facteur de mise à l'échelle réel. Multipliez la taille de votre entrée par l’échelle et rognez celle qui est trop grosse.

scale = max(maxwidth/oldwidth, maxheight/oldheight)
scaledwidth = oldwidth * scale
scaledheight = oldheight * scale
if scaledheight > maxheight:
    croptop = (scaledheight - maxheight) / 2
    cropbottom = (scaledheight - maxheight) - croptop
if scaledwidth > maxwidth:
    cropleft = (scaledwidth - maxwidth) / 2
    cropright = (scaledwidth - maxwidth) - cropleft

Autres conseils

Nous veillons ici à ne mettre à l'échelle que si X est supérieur à 100%; ensuite, nous nous assurons que nous ne sommes que 50 px sur notre Y. Si nous sommes supérieurs à 50, nous prenons la différence et divisons par 2 pour obtenir le montant retiré du haut / du bas.

double percent_x = 1.0;

if(X > 100) {
 percent_x = (float)100/X;
 X *= percent_x;
 Y *= percent_x;
}

int diff_y;
int top_cut, bott_cut;
if( Y > 50 ) {
 diff_y = (Y - 50) / 2;
 top_cut = bott_cut = diff_y;
}

Largement inspiré par la réponse de Mark Ransom (merci beaucoup, vous m'avez sauvé). Pour ceux qui voudraient faire cela sans rogner l'image (tenir dans les limites du cadre), j'ai constaté que cela fonctionnait:

if (maxWidth > width && maxHeight > height) {
  return { width, height };
}

aspectRatio = width / height,
scale       = max(maxWidth / width, maxHeight / height);

scaledHeight = height * scale,
scaledWidth  = width * scale;

if (scaledHeight > maxHeight) {
  scaledHeight = maxHeight;
  scaledWidth  = aspectRatio * scaledHeight;
} else if (scaledWidth > maxWidth) {
  scaledWidth  = maxWidth;
  scaledHeight = scaledWidth / aspectRatio;
}

return { scaledHeight, scaledWidth };
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top