Come ridimensionare un UIImageView in modo proporzionale?


341

Ho un UIImageView e l'obiettivo è ridimensionarlo proporzionalmente dandogli un'altezza o una larghezza.

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'immagine è stata ridimensionata ma la posizione non è in alto a sinistra. Qual è l'approccio migliore per ridimensionare image / imageView e come posso correggere la posizione?


Ho qualcosa di simile al tuo codice che non funziona per me "UIImage * image = [UIImage imageNamed: imageString]; UIImageView * imageView = [[[UIImage alloc] initWithImage: image];" genera un'eccezione che uccide la mia app con questa "App in chiusura a causa dell'eccezione non rilevata 'NSInvalidArgumentException', motivo: '- [UIImage initWithImage:]: selettore non riconosciuto inviato all'istanza 0xd815930'"
Spire

3
@Spire It's UIImageView not UIImage ^^
Thomas Decaux

2
Questo funziona per me. Ricorda di impostare .contentMode su UIImageView, non su UIImage. - Ecco il mio: UIImageView * imageView = [[UIImageView alloc] initWithFrame: CGRectMake (0,0,30,30)]
Jarrett Barnett,

Risposte:


541

Risolto facilmente, una volta trovata la documentazione!

 imageView.contentMode = UIViewContentModeScaleAspectFit;

19
Che cosa hai effettivamente risposto? nella domanda di Ronnie ha detto che lo usa
Dejell

3
ImageView potrebbe non tagliare. Prova imageView.layer.masksToBounds = YES;
Mackworth,

Per prima cosa ho provato con IB per assicurarmi che funzionasse come necessario, ma non ricordo il nome della variabile da impostare. Quindi ho Google e ho trovato questa risposta.
Dino Tw,

1
Per chiunque abbia lo stesso problema in Swift: ScaleAspectFitora è un enum UIViewContentMode, quindi avresti impostato imageView.contentMode = UIViewContentMode.ScaleAspectFit. Nota il periodo.
sudo make install

1
translatesAutoresizingMaskIntoConstraintsnon dovrebbe essere impostato su false. Mi ci è voluto molto tempo prima di rendermi conto che questa proprietà sta impedendo il ridimensionamento
Gerald

401

Ho visto un po 'di conversazione sui tipi di ridimensionamento, quindi ho deciso di mettere insieme un articolo su alcuni dei più popolari tipi di ridimensionamento della modalità di contenuto .

L'immagine associata è qui:

inserisci qui la descrizione dell'immagine


Come si allinea verticalmente quando AspectFit è impostato?
esbenr,

@esbenr Questo dovrebbe accadere automaticamente. Potresti essere in grado di trovare una sostituzione, se necessario, ma al momento non ne conosco una: |
Jacksonkr,

Voglio usare Aspect Fill ma voglio anche visualizzare l'immagine completa. Quindi devo modificare la dimensione "Area adatta". Come posso farlo con il layout automatico?
sottovento il

@lee Esistono diverse opzioni, ma dipende molto dalla tua situazione. Ho creato una chat SOF in modo da poter discutere del tuo argomento e ti darò le informazioni che voglio, vai avanti se sei così incline: chat.stackoverflow.com/rooms/81180/ios-autoresize-chat
Jacksonkr,

@Jackson Questo non accade automaticamente. Seleziona l'altezza dell'immagine originale prima che UIImageView la ridimensioni, quindi l'altezza NON corrisponde alla nuova altezza adattata. Se qualcuno trova un modo carino per farlo, per favore fatemelo sapere.
datWooWoo,

78

Ho appena provato questo e UIImage non supporta _imageScaledToSize.

Ho finito per aggiungere un metodo a UIImage usando una categoria - un suggerimento che ho trovato sui forum Apple Dev.

In un progetto .h -

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

Implementazione:

@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;

1
invece di UIGraphicsBeginImageContext(targetSize);fare se ([UIScreen instancesRespondToSelector:@selector(scale)]) { UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0f); } else { UIGraphicsBeginImageContext(targetSize); }supportare i display retina senza renderlo sfocato
bicicletta il

38
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;

30

Potresti provare a far imageViewcorrispondere le dimensioni a image. Il seguente codice non è testato.

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;

1
impostazione imageView.frame = XXXX (niente) non differisce in alcun modo dall'output. qualche idea del perché?
sramij,

1
@sramij Se stai utilizzando il layout automatico, assicurati di fare confusione con [setTranslatesAutoResize ...] nelle UIVview. Se non sai cosa fa controlla la documentazione! :)
datWooWoo il

13

si può ridimensionare un UIImage in questo modo

image = [UIImage imageWithCGImage:[image CGImage] scale:2.0 orientation:UIImageOrientationUp];

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]; 

Il codice originale pubblicato in alto ha funzionato bene per me in iOS 4.2.

Ho scoperto che la creazione di un CGRect e la specifica di tutti i valori superiore, sinistro, larghezza e altezza era il modo più semplice per regolare la posizione nel mio caso, che utilizzava un UIImageView all'interno di una cella di tabella. (È ancora necessario aggiungere codice per rilasciare oggetti)


13

Imposta ImageView selezionando Modalità su Aspect Fille seleziona la Clip Subviewscasella.

inserisci qui la descrizione dell'immagine


10

Questo funziona bene per me Swift 2.x:

imageView.contentMode = .ScaleAspectFill
imageView.clipsToBounds = true;


6

Per Swift:

self.imageViews.contentMode = UIViewContentMode.ScaleToFill

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

2

Ho usato il seguente code.where imageCoverView è UIView contiene 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;
}

2

Se le soluzioni proposte qui non funzionano per te e la tua risorsa immagine è in realtà un PDF, tieni presente che XCode tratta effettivamente i PDF in modo diverso rispetto ai file di immagine. In particolare, non sembra in grado di ridimensionarsi per riempirsi correttamente con un PDF: finisce invece affiancato. Questo mi ha fatto impazzire finché non ho capito che il problema era il formato PDF. Converti in JPG e dovresti essere a posto.


1

Di solito uso questo metodo per le mie app ( compatibile con 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
}

0

Penso che tu possa fare qualcosa del genere

image.center = [[imageView window] center];

3
Non ridimensionerà l'immagine ma la centrerà soltanto.
David Salzer,

-3

Ecco come puoi ridimensionarlo facilmente.

Funziona in 2.x con il simulatore e l'iPhone.

UIImage *thumbnail = [originalImage _imageScaledToSize:CGSizeMake(40.0, 40.0) interpolationQuality:1];

ciao, sai cosa interpolazioneQualità: parametro fa? grazie
user102008

27
Questo è un metodo non documentato (il carattere di sottolineatura è un omaggio morto) che potrebbe comportare il rifiuto dell'app.
Shaggy Frog,

Cosa fa il parametro interpolationQuality?
lostInTransit
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.