Как пропорционально масштабировать UIImageView?

У меня есть 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;

Размер изображения был изменен, но позиция не в верхнем левом углу. Как лучше всего масштабировать image / imageView и как исправить положение?

У меня есть что-то похожее на ваш код, который у меня не работает «UIImage * image = [UIImage imageNamed: imageString]; UIImageView * imageView = [[UIImage alloc] initWithImage: image];» вызывает исключение, которое убивает мое приложение из-за этого «Завершение приложения из-за неперехваченного исключения 'NSInvalidArgumentException', причина: '- [UIImage initWithImage:]: неопознанный селектор отправлен в экземпляр 0xd815930'»

Spire 10.03.2011 12:05

@Spire Это UIImageView, а не UIImage ^^

Thomas Decaux 12.04.2013 23:39

У меня это работает. Не забудьте установить .contentMode для вашего UIImageView, а не для вашего UIImage. - Вот мой: UIImageView * imageView = [[UIImageView alloc] initWithFrame: CGRectMake (0,0,30,30)]

Jarrett Barnett 18.06.2013 21:04
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
343
3
337 139
17

Ответы 17

Я думаю, ты можешь сделать что-то вроде

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

Изображение не масштабируется, а только центрируется.

David Salzer 17.02.2011 18:25

Вы можете попробовать подогнать размер 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;

установка imageView.frame = XXXX (что угодно) не влияет на вывод. есть идеи почему?

sramij 02.07.2014 17:09

@sramij Если вы используете автоматическое размещение, не забудьте использовать [setTranslatesAutoResize ...] в UIViews. Если вы не знаете, что это такое, проверьте документацию! :)

datWooWoo 22.06.2015 20:36

Вот как это легко масштабировать.

Это работает в 2.x с симулятором и iPhone.

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

привет, вы знаете, что делает параметр interpolationQuality :? Благодарность

user102008 22.08.2009 01:55

Это недокументированный метод (подчеркивание неуместно), который может привести к отклонению приложения.

Shaggy Frog 18.10.2009 05:08

Что делает параметр interpolationQuality?

lostInTransit 28.01.2010 11:26

Я только что попробовал, а 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;

вместо UIGraphicsBeginImageContext(targetSize); сделайте, если ([UIScreen instancesRespondToSelector:@selector(scale)]) { UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0f); } else { UIGraphicsBeginImageContext(targetSize); } поддерживает дисплеи сетчатки, не делая их размытыми

bicycle 24.02.2016 18:57

Исправить легко, как только найду документацию!

 imageView.contentMode = .scaleAspectFit

Что вы на самом деле ответили? в вопросе Ронни он упомянул, что использует это

Dejell 09.12.2012 15:19

Возможно, ваш imageView не обрезается. Попробуйте imageView.layer.masksToBounds = YES;

mackworth 27.01.2014 08:20

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

Dino Tw 20.02.2014 21:38

Для тех, у кого такая же проблема в Swift: ScaleAspectFit теперь является enum UIViewContentMode, поэтому вы должны установить imageView.contentMode = UIViewContentMode.ScaleAspectFit. Обратите внимание на период.

sudo make install 14.02.2015 13:28

translatesAutoresizingMaskIntoConstraints не должен быть установлен на false. Мне потребовалось много времени, прежде чем я понял, что это свойство предотвращает изменение размера

Gerald 12.07.2016 06:41

таким образом можно изменить размер UIImage

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

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 внутри ячейки таблицы. (Еще нужно добавить код для выпуска объектов)

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

Я видел немного разговоров о типах шкал, поэтому решил собрать статья о некоторых из самых популярных типов масштабирования в режиме контента.

Связанное изображение находится здесь:

Как вы выравниваете по вертикали, когда установлен AspectFit?

esbenr 09.04.2013 15:10

@esbenr Это должно произойти автоматически. Возможно, вы сможете найти замену по мере необходимости, но в настоящее время я не знаю ни одной: |

Jacksonkr 12.04.2013 17:34

Я хочу использовать Aspect Fill, но я также хочу отображать полное изображение. Затем мне нужно изменить размер «Площадь по размеру». Как я могу сделать это с помощью автоматического макета?

lee 22.06.2015 11:32

@lee Есть несколько вариантов, но это действительно зависит от вашей ситуации. Я создал SOF-чат, чтобы мы могли обсудить вашу тему, и я дам вам необходимую информацию, которая у меня есть, заходите, если вы так склонны: chat.stackoverflow.com/rooms/81180/ios-autoresize-chat

Jacksonkr 22.06.2015 15:53

@Jackson Это вообще не происходит автоматически. Он выбирает высоту исходного изображения до того, как UIImageView масштабирует его, поэтому высота НЕ соответствует новой высоте Aspect Fitted. Если кто-нибудь придумает хороший способ сделать это, пожалуйста, дайте мне знать.

datWooWoo 22.06.2015 20:33

Для Aspect Fill: «Обычно обрезается одна сторона, а не обе» не является точным. Я проверил это, и обрезанное изображение автоматически центрируется, обе стороны обрезаются (показан путь к изображению Google)

pixelfreak 17.10.2015 01:33

@pixelfreak Я понимаю вашу точку зрения. Чтобы устранить неоднозначность, использовалась «сторона» там, где могла быть использована «ось». Если подумать об этом дальше, изображение сжимается до тех пор, пока ось не станет заподлицо (а не обрезана).

Jacksonkr 18.04.2017 17:47

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

Установите ImageView, выбрав режим Aspect Fill и отметив поле Clip Subviews.

Для Swift:

self.imageViews.contentMode = UIViewContentMode.ScaleToFill

Я использовал следующий код. Где imageCoverView - 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;
}

Обычно я использую этот метод для своих приложений (совместимых с 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
}

Это отлично работает для меня Swift 2.x:

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

Установите UIimageview по шкале .........

Если предлагаемые здесь решения не работают для вас, а ваш ресурс изображения на самом деле является PDF-файлом, обратите внимание, что XCode фактически обрабатывает PDF-файлы иначе, чем файлы изображений. В частности, кажется, что он не может масштабироваться, чтобы правильно заполнить PDF: вместо этого он оказывается мозаичным. Это сводило меня с ума, пока я не понял, что проблема была в формате PDF. Конвертируйте в JPG, и все будет хорошо.

Другие вопросы по теме