2010-07-26 5 views
7

Je souhaite écrire une fonction permettant de réduire la taille d'une image pour l'adapter à des limites spécifiées. Par exemple, je veux redimensionner une image 2000x2333 pour tenir dans 1280x800. Le rapport d'aspect doit être conservé. J'ai trouvé l'algorithme suivant:Algorithme de redimensionnement d'image

NSSize mysize = [self pixelSize]; // just to get the size of the original image 
int neww, newh = 0; 
float thumbratio = width/height; // width and height are maximum thumbnail's bounds 
float imgratio = mysize.width/mysize.height; 

if (imgratio > thumbratio) 
{ 
    float scale = mysize.width/width; 
    newh = round(mysize.height/scale); 
    neww = width; 
} 
else 
{ 
    float scale = mysize.height/height; 
    neww = round(mysize.width/scale); 
    newh = height; 
} 

Et il a semblé fonctionner. Eh bien ... semblait. Mais j'ai ensuite essayé de redimensionner une image 1280x1024 à une limite de 1280x800 et cela m'a donné un résultat de 1280x1024 (ce qui ne correspond évidemment pas à 1280x800).

Quelqu'un a des idées sur la façon dont cet algorighme devrait fonctionner?

Répondre

26

La façon dont je le fais habituellement est de regarder le rapport entre la largeur d'origine et la nouvelle largeur et le rapport entre la hauteur d'origine et la nouvelle hauteur. Après cela, l'image est réduite par le plus grand ratio. Par exemple, si vous souhaitez redimensionner une image de 800 x 600 dans une image de 400 x 400, le rapport de largeur sera de 2 et le rapport de hauteur sera de 1,5. La réduction de l'image par un rapport de 2 donne une image de 400x300.

NSSize mysize = [self pixelSize]; // just to get the size of the original image 
int neww, newh = 0; 
float rw = mysize.width/width; // width and height are maximum thumbnail's bounds 
float rh = mysize.height/height; 

if (rw > rh) 
{ 
    newh = round(mysize.height/rw); 
    neww = width; 
} 
else 
{ 
    neww = round(mysize.width/rh); 
    newh = height; 
} 
+0

Oh, je dois ajouter pour votre exemple casting de 1280x800 les 1280x1024 rapports seraient 1 et 1,28, après la redimensionnez serait 1000 x 800 – GWW

+0

Merci! Je pense que ça marche enfin! – Marius

6

Voici une manière d'aborder le problème:

Vous savez que soit la hauteur ou la largeur de l'image sera égale à celle de la zone de délimitation.

Une fois que vous avez déterminé quelle dimension sera égale à la boîte englobante, vous utilisez le format de l'image pour calculer l'autre dimension.

double sourceRatio = sourceImage.Width/sourceImage.Height; 
double targetRatio = targetRect.Width/targetRect.Height; 

Size finalSize; 
if (sourceRatio > targetRatio) 
{ 
    finalSize = new Size(targetRect.Width, targetRect.Width/sourceRatio); 
} 
else 
{ 
    finalSize = new Size(targetRect.Height * sourceRatio, targetRect.Height); 
} 
+0

Qu'est-ce que l'imageRatio? –

+0

@JonathanAquino Je pense que c'était censé être 'sourceRatio'. Bon ramassage. –