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?

Ronnie Liew
quelle
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;
Ken Abrams
quelle
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

Jacksonkr
quelle
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;
Jane Sales
quelle
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;
Li-chih Wu
quelle
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;
Chris Lundie
quelle
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];
neoneye
quelle
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.)

Nate Flink
quelle
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

Jeffrey Neo
quelle
10

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

imageView.contentMode = .ScaleAspectFill
imageView.clipsToBounds = true;
vvamondes
quelle
9

Stellen Sie Ihre UIimageviewnach Skala ein .........

Geben Sie hier die Bildbeschreibung ein

PJRadadiya
quelle
6

Für Swift:

self.imageViews.contentMode = UIViewContentMode.ScaleToFill
Somir Saikia
quelle
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
quelle
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;
}
Avijit Nagare
quelle
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.

Lane Rettig
quelle
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
}
Alessandro Ornano
quelle
0

Ich denke du kannst so etwas machen

image.center = [[imageView window] center];
user26359
quelle
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];
kdbdallas
quelle
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