Как узнать размер изображения после применения подгонки изображения в UIImageView - PullRequest
68 голосов
/ 08 июня 2011

Я загружаю изображение в просмотр изображений в режиме «Aspect Fit».Мне нужно знать размер, до которого масштабируется мое изображение.Пожалуйста, помогите.

Ответы [ 19 ]

2 голосов
/ 24 мая 2017

Расширение Swift 3 UIImageView:

import AVFoundation

extension UIImageView {
  var imageSize: CGSize {
    if let image = image {
      return AVMakeRect(aspectRatio: image.size, insideRect: bounds).size
    }
    return CGSize.zero
  }  
}
2 голосов
/ 30 марта 2017

Эта единственная строка может выполнять эту работу

CGSize sizeInView = AVMakeRectWithAspectRatioInsideRect (imgViewFake.image.size, imgViewFake.bounds) .size;

2 голосов
/ 17 января 2015

Вот мое решение для той же проблемы: https://github.com/alexgarbarev/UIImageView-ImageFrame

Преимущества:

  • Поддерживаемые режимы UIViewContentMode
  • Можно запрашивать весы и прямоугольник отдельно
  • Можно спросить о кадре изображения прямо из UIImageView
2 голосов
/ 01 августа 2014

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

- (CGSize) sizeOfImage:(UIImage*)image inAspectFitImageView:(UIImageView*)imageView
{
    UKAssert(imageView.contentMode == UIViewContentModeScaleAspectFit, @"Image View must use contentMode = UIViewContentModeScaleAspectFit");

    CGFloat imageViewWidth = imageView.bounds.size.width;
    CGFloat imageViewHeight = imageView.bounds.size.height;

    CGFloat imageWidth = image.size.width;
    CGFloat imageHeight = image.size.height;

    CGFloat scaleFactor = MIN(imageViewWidth / imageWidth, imageViewHeight / imageHeight);

    return CGSizeMake(image.size.width*scaleFactor, image.size.height*scaleFactor);
}
2 голосов
/ 20 июня 2017

Вот мое решение без AV-основания.

Сначала вот расширение CGSize для вычисления размера, подходящего для другого размера:

extension CGSize
{
    func sizeThatFitsSize(_ aSize: CGSize) -> CGSize
    {
        let width = min(self.width * aSize.height / self.height, aSize.width)
        return CGSize(width: width, height: self.height * width / self.width)
    }
}

Таким образом, решение проблемы ОП сводится к:

let resultSize = image.size.sizeThatFitsSize(imageView.bounds.size)

Также вот еще одно расширение для подгонки прямоугольника внутри другого прямоугольника (в нем используется указанное выше расширение CGSize):

extension CGRect
{
    func rectThatFitsRect(_ aRect:CGRect) -> CGRect
    {
        let sizeThatFits = self.size.sizeThatFitsSize(aRect.size)

        let xPos = (aRect.size.width - sizeThatFits.width) / 2
        let yPos = (aRect.size.height - sizeThatFits.height) / 2

        let ret = CGRect(x: xPos, y: yPos, width: sizeThatFits.width, height: sizeThatFits.height)
        return ret
    }
}
1 голос
/ 01 июня 2017

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

-(UIImage*)imageWithImage: (UIImage*) sourceImage scaledToWidth: (float) i_width
{
    float oldWidth = sourceImage.size.width;
    float scaleFactor = i_width / oldWidth;

    float newHeight = sourceImage.size.height * scaleFactor;
    float newWidth = oldWidth * scaleFactor;

    UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
    [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    return newImage;
}

И вызывайте его из вашего cellForRowAtIndexPath: метод, подобный этому:

UIImage *img = [dictImages objectForKey:yourImageKey]; // loaded the image
cell.imgView.image = [self imageWithImage:img scaledToWidth:self.view.frame.size.width];
1 голос
/ 24 сентября 2018

Версия Swift 4

extension CGSize {
   enum AspectMode {
       case fit
       case fill
   }

   enum Orientation {
       case portrait
       case landscape
   }

   func aspectCorrectSizeToFit(targetSize: CGSize, aspectMode: AspectMode = .fill) -> CGSize {
        switch aspectMode {
        case .fill: return aspectFill(targetSize: targetSize)
        case .fit: return aspectFit(targetSize: targetSize)
        }
    }

    var orientation: Orientation {
        if height >= width { return .portrait }
        else { return .landscape }
    }

    func aspectFit(targetSize: CGSize) -> CGSize {
        let wRatio = targetSize.width / width
        let hRatio = targetSize.height / height
        let scale = min(wRatio, hRatio)
        return applying(CGAffineTransform(scaleX: scale, y: scale))
    }

    func aspectFill(targetSize: CGSize) -> CGSize {
        let wRatio = targetSize.width / width
        let hRatio = targetSize.height / height
        let scale = max(wRatio, hRatio)
        return applying(CGAffineTransform(scaleX: scale, y: scale))
    }
}
1 голос
/ 14 апреля 2016

Я использую следующее в Swift:

private func CGSizeAspectFit(aspectRatio:CGSize,boundingSize:CGSize) -> CGSize
{
    var aspectFitSize = boundingSize
    let mW = boundingSize.width / aspectRatio.width
    let mH = boundingSize.height / aspectRatio.height
    if( mH < mW )
    {
        aspectFitSize.width = mH * aspectRatio.width
    }
    else if( mW < mH )
    {
        aspectFitSize.height = mW * aspectRatio.height
    }
    return aspectFitSize
}

private func CGSizeAspectFill(aspectRatio:CGSize,minimumSize:CGSize) -> CGSize
{
    var aspectFillSize = minimumSize
    let mW = minimumSize.width / aspectRatio.width
    let mH = minimumSize.height / aspectRatio.height
    if( mH > mW )
    {
        aspectFillSize.width = mH * aspectRatio.width
    }
    else if( mW > mH )
    {
        aspectFillSize.height = mW * aspectRatio.height
    }
    return aspectFillSize
}

Я использую это так:

let aspectSize  = contentMode == .ScaleAspectFill ? CGSizeAspectFill(oldSize,minimumSize: newSize) : CGSizeAspectFit(oldSize, boundingSize: newSize)

let newRect = CGRect( x: (newSize.width - aspectSize.width)/2, y: (newSize.height - aspectSize.height)/2, width: aspectSize.width, height: aspectSize.height)

CGContextSetFillColorWithColor(context,IOSXColor.whiteColor().CGColor)
CGContextFillRect(context, CGRect(origin: CGPointZero,size: newSize))
CGContextDrawImage(context, newRect, cgImage)
0 голосов
/ 18 мая 2016

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

Определение соотношения сторон

CGFloat imageViewAspectRatio = backgroundImageView.bounds.size.width / backgroundImageView.bounds.size.height;
CGFloat imageAspectRatio =  backgroundImageView.image.size.width / backgroundImageView.image.size.height;
CGFloat mulFactor = imageViewAspectRatio/imageAspectRatio;

Получитьновые значения

CGFloat newImageWidth = mulFactor * backgroundImageView.bounds.size.width;
CGFloat newImageHeight = mulFactor * backgroundImageView.bounds.size.height;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...