ios 使用drawInRect时UIImage Aspect Fit?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8858404/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:17:19  来源:igfitidea点击:

UIImage Aspect Fit when using drawInRect?

iosuiimage

提问by Ana

UIView provides for the "aspect fit" content mode. However, I've subclasses UIView and would like to draw a UIImage using drawInRect with an aspect fit. Is there any way for me to access that functionality without using a UIImageView?

UIView 提供了“方面适合”的内容模式。但是,我已经对 UIView 进行了子类化,并且想使用带有方面适合的 drawInRect 来绘制 UIImage 。有什么方法可以让我在不使用 UIImageView 的情况下访问该功能?

回答by Nick Lockwood

The math for that is a little bit hairy, but fortunately, here's a solution I prepared earlier:

数学有点麻烦,但幸运的是,这是我之前准备的解决方案:

- (UIImage *)imageScaledToSize:(CGSize)size
{
    //create drawing context
    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);

    //draw
    [self drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)];

    //capture resultant image
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

- (UIImage *)imageScaledToFitSize:(CGSize)size
{
    //calculate rect
    CGFloat aspect = self.size.width / self.size.height;
    if (size.width / aspect <= size.height)
    {
        return [self imageScaledToSize:CGSizeMake(size.width, size.width / aspect)];
    }
    else
    {
        return [self imageScaledToSize:CGSizeMake(size.height * aspect, size.height)];
    }
}

The first function is equivalent to "scale to fill", the second (which calls the first) is equivalent to "aspect fit". These methods were written as a category on UIImage so to use them from within another class you'll need to tweak them by passing the image in as a second parameter (or just make a category on UIImage like I did).

第一个函数相当于“缩放填充”,第二个(调用第一个)相当于“方面适合”。这些方法是作为 UIImage 上的一个类别编写的,因此要在另一个类中使用它们,您需要通过将图像作为第二个参数传入来调整它们(或者像我一样在 UIImage 上创建一个类别)。

回答by Antzi

You have to draw in the rect provided by

您必须绘制由提供的矩形

Swift:

迅速:

func AVMakeRect(aspectRatio: CGSize, insideRect boundingRect: CGRect) -> CGRect

func AVMakeRect(aspectRatio: CGSize, insideRect boundingRect: CGRect) -> CGRect

Objective-C:

目标-C:

CGRect AVMakeRectWithAspectRatioInsideRect(CGSize aspectRatio, CGRect boundingRect);

See doc

文档

The aspect ratio is preserved and the drawing centred.

纵横比被保留并且绘图居中。

It works in absolutely all cases.

它绝对适用于所有情况。

回答by Haider

here's the solution

这是解决方案

CGSize imageSize = yourImage.size;
CGSize viewSize = CGSizeMake(450, 340); // size in which you want to draw

float hfactor = imageSize.width / viewSize.width;
float vfactor = imageSize.height / viewSize.height;

float factor = fmax(hfactor, vfactor);

// Divide the size by the greater of the vertical or horizontal shrinkage factor
float newWidth = imageSize.width / factor;
float newHeight = imageSize.height / factor;

CGRect newRect = CGRectMake(xOffset,yOffset, newWidth, newHeight);
[image drawInRect:newRect];

-- courtesy https://stackoverflow.com/a/1703210

- 礼貌https://stackoverflow.com/a/1703210

another alternative for aspect fit

方面适合的另一种选择

-(CGSize ) getImageSize :(CGSize )imgViewSize andActualImageSize:(CGSize )actualImageSize {

     // imgViewSize = size of view in which image is to be drawn
     // actualImageSize = size of image which is to be drawn

     CGSize drawImageSize;

     if (actualImageSize.height > actualImageSize.width) {

        drawImageSize.height = imgViewSize.height;
        drawImageSize.width = actualImageSize.width/actualImageSize.height * imgViewSize.height;

     }else {

        drawImageSize.width = imgViewSize.width;
        drawImageSize.height = imgViewSize.width * actualImageSize.height /  actualImageSize.width;
     }
     return drawImageSize;
}

Code for swift 3.0:

swift 3.0 的代码:

func getAspectFitFrame(sizeImgView:CGSize, sizeImage:CGSize) -> CGRect{

    let imageSize:CGSize  = sizeImage
    let viewSize:CGSize = sizeImgView

    let hfactor : CGFloat = imageSize.width/viewSize.width
    let vfactor : CGFloat = imageSize.height/viewSize.height

    let factor : CGFloat = max(hfactor, vfactor)

    // Divide the size by the greater of the vertical or horizontal shrinkage factor
    let newWidth : CGFloat = imageSize.width / factor
    let newHeight : CGFloat = imageSize.height / factor

    var x:CGFloat = 0.0
    var y:CGFloat = 0.0
    if newWidth > newHeight{
        y = (sizeImgView.height - newHeight)/2
    }
    if newHeight > newWidth{
        x = (sizeImgView.width - newWidth)/2
    }
    let newRect:CGRect = CGRect(x: x, y: y, width: newWidth, height: newHeight)

    return newRect

}

回答by Nathan

this might help you, give it a try

这可能对你有帮助,试试看

UIImage *logoImage = [UIImage imageNamed:@"logo.png"];

float newHeight = ((logoImage.size.height / logoImage.size.width) * 100.0);
CGRect newLogoImageRect = CGRectMake(0, 0, 80.0, newHeight);
[logoImage drawInRect:newLogoImageRect];

specify your maximum height instead of 100.0 and maximum width instead of 80.0

指定最大高度而不是 100.0 和最大宽度而不是 80.0

回答by Russian

Here's a helper CGSize extension that you might find useful:

这是您可能会发现有用的辅助 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)
    }
}

Then in -drawInRect:implementation one would do the following:

然后在-drawInRect:实现中,将执行以下操作:

let imageSizeThatFitsViewBounds = self.image.size.sizeThatFitsSize(self.bounds.size)
let imageRectX = (self.bounds.size.width - imageSizeThatFitsViewBounds.width) / 2
let imageRectY = (self.bounds.size.height - imageSizeThatFitsViewBounds.height) / 2
let imageRect = CGRect(origin: CGPoint(x: imageRectX, y: imageRectY), size: imageSizeThatFitsViewBounds)

回答by Timo

The following will let you determine the size to draw in. You specify the aspect ratio and the bounding size to fit into.

下面将让您确定要绘制的大小。您指定要适应的纵横比和边界大小。

CGSizeAspectFit & CGSizeAspectFill

CGSizeAspectFit & CGSizeAspectFill