443 votes

La façon la plus simple de redimensionner une UIImage ?

Dans mon application iPhone, je prends une photo avec l'appareil photo, puis je veux la redimensionner en 290*390 pixels. J'utilisais cette méthode pour redimensionner l'image :

UIImage *newImage = [image _imageScaledToSize:CGSizeMake(290, 390)
                         interpolationQuality:1];    

Cela fonctionne parfaitement, mais c'est une fonction non documentée, donc je ne peux plus l'utiliser avec l'iPhone OS4.

Alors... quel est le moyen le plus simple de redimensionner une UIImage ?

0 votes

La façon de le faire en 2019, nshipster.com/image-resizing

790voto

Paul Lynch Points 13774

Le moyen le plus simple est de définir le cadre de votre UIImageView et définir les contentMode à l'une des options de redimensionnement.

Vous pouvez également utiliser cette méthode utilitaire, si vous avez réellement besoin de redimensionner une image :

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
    //UIGraphicsBeginImageContext(newSize);
    // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
    // Pass 1.0 to force exact pixel size.
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    return newImage;
}

Exemple d'utilisation :

#import "MYUtil.h"
…
UIImage *myIcon = [MYUtil imageWithImage:myUIImageInstance scaledToSize:CGSizeMake(20, 20)];

11 votes

Je ne retiendrais PAS le résultat ici. newImage sera déjà libéré automatiquement, et c'est à la méthode qui l'a appelé de le conserver ou non. Cette approche ne peut que provoquer un bug de mémoire puisque init ne fait pas partie du nom de la méthode. Je m'attendrais à ce qu'une méthode nommée de la sorte renvoie un objet autoreleased.

0 votes

Un point valable, et édité. Je vais juste laisser l'avertissement que mon code qui utilise cela génère des erreurs de malloc ailleurs sans retenue supplémentaire, ce qui est clairement ma faute d'une manière ou d'une autre :-).

29 votes

À partir d'iOS 4.0 les fonctions UIGraphics* sont toutes à l'abri des fils.

92voto

Rogerio Chaves Points 386

Voici une version Swift de La réponse de Paul Lynch

func imageWithImage(image:UIImage, scaledToSize newSize:CGSize) -> UIImage{
    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
    image.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
}

Et comme une extension :

public extension UIImage {
    func copy(newSize: CGSize, retina: Bool = true) -> UIImage? {
        // In next line, pass 0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
        // Pass 1 to force exact pixel size.
        UIGraphicsBeginImageContextWithOptions(
            /* size: */ newSize,
            /* opaque: */ false,
            /* scale: */ retina ? 0 : 1
        )
        defer { UIGraphicsEndImageContext() }

        self.draw(in: CGRect(origin: .zero, size: newSize))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

2 votes

Notez simplement que, dans iOS, votre newSize sera multiplié par 2x, 3x en fonction du périphérique.

9 votes

UIGraphicsBeginImageContextWithOptions(newSize, false, image.scale) ; pour tous les appareils

0 votes

Notez que cela ne redimensionne pas l'image CGI sous-jacente (du moins dans iOS 12.1). Ce qui est correct au vu de la question, mais si vous écrivez l'image, vous devrez utiliser le cgImage, et vous obtiendrez l'image originale.

31voto

TechZen Points 52692

Trevor Howard a quelques Catégories d'images UIImage qui gèrent très bien le redimensionnement. Vous pouvez utiliser le code à titre d'exemple.

Remarque : à partir d'iOS 5.1, cette réponse n'est peut-être plus valable. Voir le commentaire ci-dessous.

2 votes

J'avais aussi besoin de redimensionner des images, et j'ai d'abord essayé les ajouts de Trevor à UIImage, mais j'ai eu des bugs bizarres sur les PNG (quelque chose à propos du canal alpha). La réponse acceptée à cette question a bien fonctionné.

1 votes

Ce n'est plus valable (du moins avec iOS5.1).

0 votes

@Jann, regardez les commits en dessous du post.

26voto

iWasRobbed Points 26926

J'ai également vu cette façon de faire (que j'utilise sur UIButtons pour les états Normal et Sélectionné, car les boutons ne sont pas resize pour s'adapter). Le crédit revient à l'auteur original, quel qu'il soit.

Créez d'abord un fichier .h et .m vide appelé UIImageResizing.h y UIImageResizing.m

// Put this in UIImageResizing.h
@interface UIImage (Resize)
- (UIImage*)scaleToSize:(CGSize)size;
@end

// Put this in UIImageResizing.m
@implementation UIImage (Resize)

- (UIImage*)scaleToSize:(CGSize)size {
UIGraphicsBeginImageContext(size);

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0.0, size.height);
CGContextScaleCTM(context, 1.0, -1.0);

CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, size.width, size.height), self.CGImage);

UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return scaledImage;
}

@end

Incluez ce fichier .h dans le fichier .m dans lequel vous allez utiliser la fonction, puis appelez-la comme ceci :

UIImage* image = [UIImage imageNamed:@"largeImage.png"];
UIImage* smallImage = [image scaleToSize:CGSizeMake(100.0f,100.0f)];

0 votes

Cela ne permet pas de copier l'orientation de l'image.

20voto

malcolmhall Points 1909

Cette amélioration du code de Paul vous permettra d'obtenir une image haute résolution nette sur un iPhone doté d'un écran rétina. Sinon, lorsque l'on réduit l'échelle, l'image est floue.

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    if ([[UIScreen mainScreen] scale] == 2.0) {
        UIGraphicsBeginImageContextWithOptions(newSize, YES, 2.0);
    } else {
        UIGraphicsBeginImageContext(newSize);
    }
} else {
    UIGraphicsBeginImageContext(newSize);
}
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
UIGraphicsEndImageContext();
return newImage;
}

13 votes

Pour votre information, les modifications que vous avez apportées sont inutiles, car si vous fournissez une valeur de 0,0 pour l'échelle dans l'option UIGraphicsBeginImageContextWithOptions utilisera automatiquement l'échelle de l'écran principal (à partir de iOS 3.2).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X