Wie skaliere ich eine UIImageView proportional?


341

Ich habe ein UIImageView und das Ziel ist es, es proportional zu verkleinern, indem ich ihm entweder eine Höhe oder eine Breite gebe.

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;

Die Bildgröße wurde geändert, aber die Position befindet sich nicht oben links. Was ist der beste Ansatz zum Skalieren von Bild / Bildansicht und wie korrigiere ich die Position?


Ich habe etwas Ähnliches wie Ihr Code, das für mich nicht funktioniert. "UIImage * image = [UIImage imageNamed: imageString]; UIImageView * imageView = [[UIImage alloc] initWithImage: image];" löscht eine Ausnahme, die meine App mit dieser "Beenden der App aufgrund einer nicht erfassten Ausnahme 'NSInvalidArgumentException' beendet, Grund: '- [UIImage initWithImage:]: nicht erkannter Selektor an Instanz 0xd815930 gesendet'"
Spire

3
@Spire Es ist UIImageView nicht UIImage ^^
Thomas Decaux

2
Das funktioniert bei mir. Denken Sie daran, den .contentMode auf Ihre UIImageView festzulegen - nicht auf Ihre UIImage. - Hier ist meins: UIImageView * imageView = [[UIImageView alloc] initWithFrame: CGRectMake (0,0,30,30)]
Jarrett Barnett

Antworten:


541

Einfach behoben, sobald ich die Dokumentation gefunden habe!

 imageView.contentMode = UIViewContentModeScaleAspectFit;

19
Was hast du eigentlich beantwortet? In Ronnies Frage erwähnte er, dass er es benutzt
Dejell

3
Ihre imageView schneidet möglicherweise nicht ab. Versuchen Sie imageView.layer.masksToBounds = YES;
Mackworth

Ich habe zuerst mit IB versucht, um sicherzustellen, dass es nach Bedarf funktioniert, aber ich erinnere mich nicht an den zu setzenden Variablennamen. Also google ich es und fand diese Antwort.
Dino Tw

1
Für alle, die das gleiche Problem in Swift haben: ScaleAspectFitist jetzt ein enum UIViewContentMode, also würden Sie einstellen imageView.contentMode = UIViewContentMode.ScaleAspectFit. Beachten Sie den Zeitraum.
Sudo Make Install

1
translatesAutoresizingMaskIntoConstraintssollte nicht eingestellt werden false. Es hat lange gedauert, bis mir klar wurde, dass diese Eigenschaft die Größenänderung verhindert
Gerald

401

Ich habe einige Gespräche über Skalierungstypen geführt, daher habe ich beschlossen, einen Artikel über einige der beliebtesten Skalierungstypen im Inhaltsmodus zusammenzustellen .

Das zugehörige Bild ist hier:

Geben Sie hier die Bildbeschreibung ein


Wie richten Sie vertikal aus, wenn AspectFit eingestellt ist?
Esbenr

@esbenr Das sollte automatisch passieren. Möglicherweise können Sie bei Bedarf einen Override finden, aber ich kenne derzeit keinen: |
Jacksonkr

Ich möchte Aspect Fill verwenden, aber ich möchte auch das vollständige Bild anzeigen. Dann muss ich die Größe des Bereichs ändern, um ihn anzupassen. Wie kann ich das mit Auto-Layout machen?
Lee

@lee Es gibt eine Reihe von Optionen, aber es hängt wirklich von Ihrer Situation ab. Ich habe einen SOF-Chat erstellt, damit wir Ihr Thema diskutieren können, und ich gebe Ihnen Informationen, die ich habe. Schauen
Jacksonkr

@Jackson Das passiert überhaupt nicht automatisch. Es wählt die Höhe des Originalbilds aus, bevor UIImageView es skaliert, sodass die Höhe NICHT mit der neuen Höhe des angepassten Aspekts übereinstimmt. Wenn jemand einen guten Weg findet, lassen Sie es mich bitte wissen.
datWooWoo

78

Ich habe es gerade versucht und UIImage unterstützt _imageScaledToSize nicht.

Am Ende habe ich UIImage mithilfe einer Kategorie eine Methode hinzugefügt - ein Vorschlag, den ich in den Apple Dev-Foren gefunden habe.

In einer projektweiten .h -

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

Implementierung:

@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
anstatt zu UIGraphicsBeginImageContext(targetSize);tun, wenn ([UIScreen instancesRespondToSelector:@selector(scale)]) { UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0f); } else { UIGraphicsBeginImageContext(targetSize); }Retina-Displays zu unterstützen, ohne es verschwommen zu machen
Fahrrad

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

30

Sie können versuchen, die imageViewGröße an die anzupassen image. Der folgende Code wird nicht getestet.

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
Das Setzen von imageView.frame = XXXX (irgendetwas) unterscheidet sich nicht von der Ausgabe. Irgendeine Idee warum?
Sramij

1
@sramij Wenn Sie Autolayout verwenden, stellen Sie sicher, dass Sie in den UIViews mit [setTranslatesAutoResize ...] herumspielen. Wenn Sie nicht wissen, was das bedeutet, überprüfen Sie die Dokumentation! :)
datWooWoo

13

Auf diese Weise kann die Größe eines UIImage geändert werden

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

Der oben veröffentlichte Originalcode hat in iOS 4.2 für mich gut funktioniert.

Ich fand, dass das Erstellen eines CGRect und das Angeben aller Werte für oben, links, Breite und Höhe in meinem Fall, in dem eine UIImageView in einer Tabellenzelle verwendet wurde, die einfachste Möglichkeit war, die Position anzupassen. (Es muss noch Code hinzugefügt werden, um Objekte freizugeben.)


13

Stellen Sie Ihre ImageView ein, indem Sie Modus auf auswählen Aspect Fillund das Kontrollkästchen aktivieren Clip Subviews.

Geben Sie hier die Bildbeschreibung ein


10

Das funktioniert gut für mich Swift 2.x:

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



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

Ich habe folgenden Code verwendet. Wo imageCoverView ist, enthält UIView 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

Wenn die hier vorgeschlagenen Lösungen für Sie nicht funktionieren und Ihr Bildbestandteil tatsächlich ein PDF ist, beachten Sie, dass XCode PDFs tatsächlich anders behandelt als Bilddateien. Insbesondere scheint es nicht skalierbar zu sein, um es richtig mit einem PDF zu füllen: Es wird stattdessen gekachelt. Das machte mich verrückt, bis ich herausfand, dass das Problem das PDF-Format war. Konvertieren Sie in JPG und Sie sollten bereit sein zu gehen.


1

Normalerweise verwende ich diese Methode für meine Apps ( Swift 2.x- kompatibel):

// 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

Ich denke du kannst so etwas machen

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

3
Das Bild wird nicht skaliert, sondern nur zentriert.
David Salzer

-3

So können Sie es einfach skalieren.

Dies funktioniert in 2.x mit dem Simulator und dem iPhone.

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

Hallo, wissen Sie, was der Parameter interpolationQuality: bewirkt? danke
user102008

27
Dies ist eine undokumentierte Methode (der Unterstrich ist ein totes Werbegeschenk), die zur Ablehnung der App führen kann.
Shaggy Frog

Was macht der Parameter interpolationQuality?
lostInTransit
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.