【问题标题】:UIImage Aspect Fit when using drawInRect?使用drawInRect时UIImage Aspect Fit?
【发布时间】:2012-01-13 22:57:22
【问题描述】:

UIView 提供了“方面适合”的内容模式。但是,我将 UIView 子类化,并希望使用 drawInRect 绘制一个 UIImage 并具有适合的方面。我有什么方法可以在不使用 UIImageView 的情况下访问该功能?

【问题讨论】:

    标签: ios uiimage


    【解决方案1】:

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

    - (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)];
        }
    }
    

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

    【讨论】:

    • 我意识到我有点死线了,但是:为什么 0.0f 用于图形上下文的缩放?
    • 如果您使用 0.0,那么它将根据设备是否具有 Retina 屏幕自动选择 1.0 或 2.0。
    • 太棒了,确实如此。谢谢!我以前从没听说过那个。我想我应该更频繁地阅读文档:)
    • @Antzi 的答案现在不是更好吗,建议使用 AVMakeRectWithAspectRatioInsideRect(_ aspectRatio?还是需要手动调整大小?
    • 我最喜欢的年度评论:// return image
    【解决方案2】:

    您必须在

    提供的矩形中绘制

    斯威夫特:

    func AVMakeRect(aspectRatio: CGSize, insideRect boundingRect: CGRect) -&gt; CGRect

    目标-C:

    CGRect AVMakeRectWithAspectRatioInsideRect(CGSize aspectRatio, CGRect boundingRect);
    

    doc

    保留纵横比并居中绘制。

    它绝对适用于所有情况。

    【讨论】:

    • 这是最好的解决方案,如果你想使用它记得import AVFoundation
    【解决方案3】:

    解决办法

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

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

    方面拟合的另一种选择

    -(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;
    }
    

    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
    
    }
    

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

        这是一个帮助 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)
            }
        }
        

        然后在-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)
        

        【讨论】:

          【解决方案6】:

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

          CGSizeAspectFit & CGSizeAspectFill

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-03-17
            • 1970-01-01
            • 1970-01-01
            • 2016-12-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多