Comment mettre à l'échelle une UIImageView proportionnellement?

341

J'ai un UIImageView et l'objectif est de le réduire proportionnellement en lui donnant soit une hauteur soit une largeur.

UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://farm4.static.flickr.com/3092/2915896504_a88b69c9de.jpg"]]];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; 

//Add image view
[self.view addSubview:imageView];   

//set contentMode to scale aspect to fit
imageView.contentMode = UIViewContentModeScaleAspectFit;

//change width of frame
CGRect frame = imageView.frame;
frame.size.width = 100;
imageView.frame = frame;

L'image a été redimensionnée mais la position n'est pas en haut à gauche. Quelle est la meilleure approche pour mettre à l'échelle l'image / imageView et comment puis-je corriger la position?

Ronnie Liew
la source
J'ai quelque chose de similaire à votre code qui ne fonctionne pas pour moi "UIImage * image = [UIImage imageNamed: imageString]; UIImageView * imageView = [[UIImage alloc] initWithImage: image];" génère une exception qui tue mon application avec cette "application en cours de terminaison en raison d'une exception non interceptée 'NSInvalidArgumentException', raison: '- [UIImage initWithImage:]: sélecteur non reconnu envoyé à l'instance 0xd815930'"
Spire
3
@Spire It's UIImageView not UIImage ^^
Thomas Decaux
2
Cela fonctionne pour moi. N'oubliez pas de définir le .contentMode sur votre UIImageView - pas sur votre UIImage. - Voici le mien: UIImageView * imageView = [[UIImageView alloc] initWithFrame: CGRectMake (0,0,30,30)]
Jarrett Barnett

Réponses:

541

Fixé facilement, une fois que j'ai trouvé la documentation!

 imageView.contentMode = UIViewContentModeScaleAspectFit;
Ken Abrams
la source
19
Qu'avez-vous réellement répondu? dans la question de Ronnie, il a mentionné qu'il l'utilisait
Dejell
3
Votre imageView n'est peut-être pas écrêtée. Essayez imageView.layer.masksToBounds = YES;
mackworth
J'ai d'abord essayé avec IB pour m'assurer que cela fonctionnerait selon les besoins, mais je ne me souviens pas du nom de variable à définir. Je l'ai donc Google et trouvé cette réponse.
Dino Tw
1
Pour tous ceux qui ont le même problème dans Swift: ScaleAspectFitest maintenant un enum UIViewContentMode, vous devez donc définir imageView.contentMode = UIViewContentMode.ScaleAspectFit. Notez la période.
sudo make install
1
translatesAutoresizingMaskIntoConstraintsne doit pas être défini sur false. Cela m'a pris beaucoup de temps avant de réaliser que cette propriété empêche le redimensionnement
Gerald
401

J'ai vu un peu de conversation sur les types d'échelle, j'ai donc décidé de rédiger un article concernant certains des types d'échelle de mode de contenu les plus populaires .

L'image associée est ici:

entrez la description de l'image ici

Jacksonkr
la source
Comment alignez-vous verticalement lorsque AspectFit est défini?
esbenr
@esbenr Cela devrait se produire automatiquement. Vous pourriez être en mesure de trouver un remplacement au besoin, mais je n'en connais pas actuellement: |
Jacksonkr
Je veux utiliser le remplissage d'aspect mais je veux également afficher l'image complète. Ensuite, je dois changer la taille de la zone à adapter. Comment puis-je faire cela avec la mise en page automatique?
Lee
@lee Il existe un certain nombre d'options, mais cela dépend vraiment de votre situation. J'ai créé un chat SOF afin que nous puissions discuter de votre sujet et je vous donnerai les informations que je veux, rendez-vous si vous êtes si enclin: chat.stackoverflow.com/rooms/81180/ios-autoresize-chat
Jacksonkr
@Jackson Cela ne se produit pas du tout automatiquement. Il choisit la hauteur de l'image d'origine avant que l'UIImageView ne la redimensionne, de sorte que la hauteur ne correspond PAS à la nouvelle hauteur ajustée à l'aspect. Si quelqu'un trouve une bonne façon de procéder, faites-le moi savoir.
datWooWoo
78

Je viens d'essayer cela et UIImage ne prend pas en charge _imageScaledToSize.

J'ai fini par ajouter une méthode à UIImage en utilisant une catégorie - une suggestion que j'ai trouvée sur les forums Apple Dev.

Dans un .h à l'échelle du projet -

@interface UIImage (Extras)
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;
@end;

La mise en oeuvre:

@implementation UIImage (Extras)

- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize {

    UIImage *sourceImage = self;
    UIImage *newImage = nil;

    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;

    CGFloat targetWidth = targetSize.width;
    CGFloat targetHeight = targetSize.height;

    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;

    CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

    if (CGSizeEqualToSize(imageSize, targetSize) == NO) {

        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;

        if (widthFactor < heightFactor) 
            scaleFactor = widthFactor;
        else
            scaleFactor = heightFactor;

        scaledWidth  = width * scaleFactor;
        scaledHeight = height * scaleFactor;

        // center the image

        if (widthFactor < heightFactor) {
            thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 
        } else if (widthFactor > heightFactor) {
            thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
        }
    }


    // this is actually the interesting part:

    UIGraphicsBeginImageContext(targetSize);

    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width  = scaledWidth;
    thumbnailRect.size.height = scaledHeight;

    [sourceImage drawInRect:thumbnailRect];

    newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    if(newImage == nil) NSLog(@"could not scale image");


    return newImage ;
}

@end;
Jane Sales
la source
1
au lieu de UIGraphicsBeginImageContext(targetSize);faire si ([UIScreen instancesRespondToSelector:@selector(scale)]) { UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0f); } else { UIGraphicsBeginImageContext(targetSize); }pour soutenir les écrans rétiniens sans les rendre flous
vélo
38
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
Li-chih Wu
la source
30

Vous pouvez essayer de faire correspondre la imageViewtaille au image. Le code suivant n'est pas testé.

CGSize kMaxImageViewSize = {.width = 100, .height = 100};
CGSize imageSize = image.size;
CGFloat aspectRatio = imageSize.width / imageSize.height;
CGRect frame = imageView.frame;
if (kMaxImageViewSize.width / aspectRatio <= kMaxImageViewSize.height) 
{
    frame.size.width = kMaxImageViewSize.width;
    frame.size.height = frame.size.width / aspectRatio;
} 
else 
{
    frame.size.height = kMaxImageViewSize.height;
    frame.size.width = frame.size.height * aspectRatio;
}
imageView.frame = frame;
Chris Lundie
la source
1
définir imageView.frame = XXXX (n'importe quoi) ne change rien à la sortie. une idée pourquoi?
sramij
1
@sramij Si vous utilisez la mise en page automatique, assurez-vous de jouer avec [setTranslatesAutoResize ...] sur les UIViews. Si vous ne savez pas ce que cela signifie, consultez la documentation! :)
datWooWoo
13

on peut redimensionner un UIImage de cette façon

image = [UIImage imageWithCGImage:[image CGImage] scale:2.0 orientation:UIImageOrientationUp];
neoneye
la source
13
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://farm4.static.flickr.com/3092/2915896504_a88b69c9de.jpg"]]];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; 


//set contentMode to scale aspect to fit
imageView.contentMode = UIViewContentModeScaleAspectFit;

//change width of frame
//CGRect frame = imageView.frame;
//frame.size.width = 100;
//imageView.frame = frame;

//original lines that deal with frame commented out, yo.
imageView.frame = CGRectMake(10, 20, 60, 60);

...

//Add image view
[myView addSubview:imageView]; 

Le code original affiché en haut a bien fonctionné pour moi dans iOS 4.2.

J'ai trouvé que la création d'un CGRect et la spécification de toutes les valeurs du haut, de la gauche, de la largeur et de la hauteur étaient le moyen le plus simple d'ajuster la position dans mon cas, qui utilisait une UIImageView à l'intérieur d'une cellule de tableau. (Encore besoin d'ajouter du code pour libérer des objets)

Nate Flink
la source
13

Configurez votre ImageView en sélectionnant Mode sur Aspect Fillet cochez la Clip Subviewscase.

entrez la description de l'image ici

Jeffrey Neo
la source
10

Cela fonctionne bien pour moi Swift 2.x:

imageView.contentMode = .ScaleAspectFill
imageView.clipsToBounds = true;
vvamondes
la source
9

Définissez votre UIimageviewéchelle .........

entrez la description de l'image ici

PJRadadiya
la source
6

Pour Swift:

self.imageViews.contentMode = UIViewContentMode.ScaleToFill
Somir Saikia
la source
5

UIImageView + Scale.h:

#import <Foundation/Foundation.h>

@interface UIImageView (Scale)

-(void) scaleAspectFit:(CGFloat) scaleFactor;

@end

UIImageView + Scale.m:

#import "UIImageView+Scale.h"

@implementation UIImageView (Scale)


-(void) scaleAspectFit:(CGFloat) scaleFactor{

    self.contentScaleFactor = scaleFactor;
    self.transform = CGAffineTransformMakeScale(scaleFactor, scaleFactor);

    CGRect newRect = self.frame;
    newRect.origin.x = 0;
    newRect.origin.y = 0;
    self.frame = newRect;
}

@end
Peter Kreinz
la source
2

J'ai utilisé le code suivant. Où imageCoverView est UIView contient UIImageView

if (image.size.height<self.imageCoverView.bounds.size.height && image.size.width<self.imageCoverView.bounds.size.width)
{
    [self.profileImageView sizeToFit];
    self.profileImageView.contentMode =UIViewContentModeCenter
}
else
{
    self.profileImageView.contentMode =UIViewContentModeScaleAspectFit;
}
Avijit Nagare
la source
2

Si les solutions proposées ici ne fonctionnent pas pour vous et que votre élément d'image est en fait un PDF, notez que XCode traite en fait les PDF différemment des fichiers d'image. En particulier, il ne semble pas capable de s'adapter pour se remplir correctement avec un PDF: il finit par être carrelé à la place. Cela m'a rendu fou jusqu'à ce que je comprenne que le problème était le format PDF. Convertissez-vous en JPG et vous devriez être prêt à partir.

Lane Rettig
la source
1

Habituellement, j'utilise cette méthode pour mes applications ( compatible Swift 2.x ):

// Resize UIImage
func resizeImage(image:UIImage, scaleX:CGFloat,scaleY:CGFloat) ->UIImage {
    let size = CGSizeApplyAffineTransform(image.size, CGAffineTransformMakeScale(scaleX, scaleY))
    let hasAlpha = true
    let scale: CGFloat = 0.0 // Automatically use scale factor of main screen

    UIGraphicsBeginImageContextWithOptions(size, !hasAlpha, scale)
    image.drawInRect(CGRect(origin: CGPointZero, size: size))

    let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return scaledImage
}
Alessandro Ornano
la source
0

Je pense que vous pouvez faire quelque chose comme

image.center = [[imageView window] center];
user26359
la source
3
Il ne mettra pas à l'échelle l'image mais la centrera uniquement.
David Salzer
-3

Voici comment vous pouvez l'adapter facilement.

Cela fonctionne en 2.x avec le simulateur et l'iPhone.

UIImage *thumbnail = [originalImage _imageScaledToSize:CGSizeMake(40.0, 40.0) interpolationQuality:1];
kdbdallas
la source
salut, savez-vous ce que fait le paramètre interpolationQuality:? merci
user102008
27
Il s'agit d'une méthode non documentée (le trait de soulignement est un cadeau mort) qui pourrait entraîner le rejet de l'application.
Shaggy Frog
Que fait le paramètre interpolationQuality?
lostInTransit