Як пропорційно масштабувати UIImageView?


341

У мене є UIImageView, а мета - зменшити його пропорційно, надаючи або висоту, або ширину.

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;

Зображення отримало зміни розміру, але положення не вгорі зліва. Який найкращий підхід до масштабування зображення / imageView і як виправити положення?


У мене є щось подібне до вашого коду, що не працює для мене "UIImage * image = [UIImage imageNamed: imageString]; UIImageView * imageView = [[UIImage alloc] initWithImage: image];" запускає виняток, який вбиває мою програму під цим "Закінчення програми через невиконаний виняток" NSInvalidArgumentException ", причина: '- [UIImage initWithImage:]: нерозпізнаний селектор надісланий до екземпляра 0xd815930'"
Шпиль

3
@Spire It UIImageView not UIImage ^^
Thomas Decaux

2
Це працює для мене. Не забудьте встановити .contentMode на свій UIImageView - не на ваш UIImage. - Ось моя: UIImageView * imageView = [[UIImageView alloc] initWithFrame: CGRectMake (0,0,30,30)]
Jarrett Barnett

Відповіді:


541

Виправлено легко, як тільки я знайшов документацію!

 imageView.contentMode = UIViewContentModeScaleAspectFit;

19
Що ти насправді відповів? у запитанні Ронні він зазначив, що він його використовує
Dejell

3
Можливо, ваше зображенняView не відсікається. Спробуйте imageView.layer.masksToBounds = ТАК;
mackworth

Я спершу спробував із IB переконатися, що він буде працювати, як потрібно, але я не пам’ятаю ім'я змінної, яку потрібно встановити. Тому я Google це і знайшов цю відповідь.
Dino Tw

1
Для тих, хто має таку саму проблему у Swift: ScaleAspectFitзараз це enum UIViewContentMode, тому ви б встановили imageView.contentMode = UIViewContentMode.ScaleAspectFit. Зверніть увагу на період.
sudo make install

1
translatesAutoresizingMaskIntoConstraintsне слід встановлювати false. Зайняв мене багато часу, перш ніж зрозумів, що ця власність перешкоджає зміні розміру
Джеральд

401

Я бачив трохи розмов про типи масштабів, тому вирішив скласти статтю про деякі найпопулярніші типи масштабування вмістового режиму .

Пов'язане зображення тут:

введіть тут опис зображення


Як ви вирівнюєте вертикаль, коли встановлено AspectFit?
esbenr

@esbenr Це має відбутися автоматично. Можливо, ви зможете знайти переопрацювання за потребою, але на даний момент я не знаю: |
Джексонкр

Я хочу використовувати Aspect Fill, але також хочу показати повне зображення. Тоді мені потрібно змінити розмір "Площа на придатну". Як я можу це зробити за допомогою автоматичного компонування?
Лі

@lee Існує ряд варіантів, але це дійсно залежить від вашої ситуації. Я створив SOF чат, щоб ми могли обговорити вашу тему, і я дам вам потрібну інформацію, яку я маю, перейдіть, якщо ви так схильні: chat.stackoverflow.com/rooms/81180/ios-autoresize-chat
Jacksonkr

@Jackson Це взагалі не відбувається автоматично. Він вибирає висоту вихідного зображення до того, як масштаб UIImageView масштабує його, тому висота НЕ відповідає новій висоті встановленого аспекту. Якщо хтось з'ясує хороший спосіб зробити це, будь ласка, дайте мені знати.
datWooWoo

78

Я просто спробував це, і UIImage не підтримує _imageScaledToSize.

Я в кінцевому підсумку додав метод до UIImage за допомогою категорії - пропозицію, яку я знайшов на форумах Apple Dev.

У проекті .h -

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

Впровадження:

@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
замість UIGraphicsBeginImageContext(targetSize);робити, якщо ([UIScreen instancesRespondToSelector:@selector(scale)]) { UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0f); } else { UIGraphicsBeginImageContext(targetSize); }підтримувати сітківку дисплеїв, не роблячи її розмитою
велосипед


30

Ви можете спробувати imageViewпорівняти розмір з image. Наступний код не перевіряється.

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
встановлення imageView.frame = XXXX (що завгодно) не відрізняється від виводу. будь-яка ідея чому?
sramij

1
@sramij Якщо ви використовуєте автоматичний розклад, обов'язково поводьтесь із [setTranslatesAutoResize ...] на UIViews. Якщо ви не знаєте, що це перевіряє документацію! :)
datWooWoo

13

таким чином можна змінити розмір UIImage

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

Оригінальний код, розміщений вгорі, добре працював для мене в iOS 4.2.

Я виявив, що створення CGRect та визначення всіх верхніх, лівих, ширини та висоти значень було найпростішим способом коригування положення в моєму випадку, який використовував UIImageView всередині комірки таблиці. (Ще потрібно додати код для випуску об'єктів)



10

Для мене це працює чудово 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 + Масштаб.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

Я використовував наступний code.where imageCoverView is UIView has 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

Якщо запропоновані тут рішення не працюють для вас, а ваш актив зображення - це фактично PDF, зауважте, що XCode насправді трактує PDF-файли інакше, ніж файли зображень. Зокрема, здається, не в змозі масштабувати належним чином заповнити PDF: він закінчується кахлем. Це зводило мене з розуму, поки я не зрозумів, що проблема - це формат PDF. Конвертувати в JPG, і вам слід добре поїхати.


1

Зазвичай я використовую цей метод для своїх додатків ( сумісний 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
}


-3

Ось як можна легко його масштабувати.

Це працює в 2.x за допомогою Симулятора та iPhone.

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

привіт, чи знаєш ти, що робить параметр interpolationQuality: спасибі
користувач102008

27
Це незадокументований метод (підкреслення є мертвим піддаванням), який може призвести до відхилення програми.
Shaggy Frog

Що робить параметр interpolationQuality?
LostInTransit
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.