【问题标题】:Confused about NSImageView scaling对 NSImageView 缩放感到困惑
【发布时间】:2012-11-24 20:56:41
【问题描述】:

我正在尝试显示一个简单的 NSImageView,它的图像居中而不像这样缩放:

就像 iOS 设置 UIView 的 contentMode = UIViewContentModeCenter

所以我尝试了所有 NSImageScaling 值,这是我选择 NSScaleNone

时得到的

我真的不明白发生了什么:-/

【问题讨论】:

    标签: cocoa nsimageview


    【解决方案1】:

    您可以手动生成正确大小和内容的图像,并将其设置为 NSImageView 的图像,这样 NSImageView 就不需要做任何事情了。

    NSImage *newImg = [self resizeImage:sourceImage size:newSize];
    [aNSImageView setImage:newImg];
    

    以下函数调整图像大小以适应新大小,同时保持纵横比不变。如果图像小于新尺寸,则将其放大并用新框架填充。如果图像大于新尺寸,则缩小尺寸,并用新框架填充

    - (NSImage*) resizeImage:(NSImage*)sourceImage size:(NSSize)size{
    
    NSRect targetFrame = NSMakeRect(0, 0, size.width, size.height);
    NSImage*  targetImage = [[NSImage alloc] initWithSize:size];
    
    NSSize sourceSize = [sourceImage size];
    
    float ratioH = size.height/ sourceSize.height;
    float ratioW = size.width / sourceSize.width;
    
    NSRect cropRect = NSZeroRect;
    if (ratioH >= ratioW) {
        cropRect.size.width = floor (size.width / ratioH);
        cropRect.size.height = sourceSize.height;
    } else {
        cropRect.size.width = sourceSize.width;
        cropRect.size.height = floor(size.height / ratioW);
    }
    
    cropRect.origin.x = floor( (sourceSize.width - cropRect.size.width)/2 );
    cropRect.origin.y = floor( (sourceSize.height - cropRect.size.height)/2 );
    
    
    
    [targetImage lockFocus];
    
    [sourceImage drawInRect:targetFrame
                   fromRect:cropRect       //portion of source image to draw
                  operation:NSCompositeCopy  //compositing operation
                   fraction:1.0              //alpha (transparency) value
             respectFlipped:YES              //coordinate system
                      hints:@{NSImageHintInterpolation:
     [NSNumber numberWithInt:NSImageInterpolationLow]}];
    
    [targetImage unlockFocus];
    
    return targetImage;}
    

    【讨论】:

    • 如果您想要具有某些纵横比选项的设备:here you go
    【解决方案2】:

    这是一个很棒的 NSImage 类别:NSImage+ContentMode

    它支持 iOS 中的内容模式,效果很好。

    【讨论】:

    • 优秀。注意:对于 MacOS,您需要将 UIGraphicsGetCurrentContext() 替换为 [NSGraphicsContext currentContext].CGContext。在 High Sierra 在 CABasicAnimation 期间弄乱 NSImageView 内容后特别有用
    • 当 h>w 时,AspectFit 对我来说无法正常工作。这是有效的:if (contentMode == UIViewContentModeScaleAspectFit) { CGSize imageSize = CGSizeMake(self.size.width, self.size.height); CGSize containerSize = rect.size; CGFloat widthRaport = containerSize.width/imageSize.width; CGFloat heightRaport = containerSize.height/imageSize.height; CGFloat scale = MIN(widthRaport, heightRaport); imageSize.width = imageSize.width * scale; imageSize.height = imageSize.height * scale;
    【解决方案3】:

    将图像缩放属性设置为 NSImageScaleAxesIndependently,它将缩放图像以填充矩形。这不会保留纵横比。

    【讨论】:

      【解决方案4】:

      @Shagru 答案的 Swift 版本(没有提示)

      func resizeImage(_ sourceImage:NSImage, size:CGSize) -> NSImage
          {
              let targetFrame = CGRect(origin: CGPoint.zero, size: size);
              let targetImage = NSImage.init(size: size)
              let sourceSize = sourceImage.size
              let ratioH = size.height / sourceSize.height;
              let ratioW = size.width / sourceSize.width;
      
              var cropRect = CGRect.zero;
              if (ratioH >= ratioW) {
                  cropRect.size.width = floor (size.width / ratioH);
                  cropRect.size.height = sourceSize.height;
              } else {
                  cropRect.size.width = sourceSize.width;
                  cropRect.size.height = floor(size.height / ratioW);
              }
      
              cropRect.origin.x = floor( (sourceSize.width - cropRect.size.width)/2 );
              cropRect.origin.y = floor( (sourceSize.height - cropRect.size.height)/2 );
              targetImage.lockFocus()
              sourceImage.draw(in: targetFrame, from: cropRect, operation: .copy, fraction: 1.0, respectFlipped: true, hints: nil )
      
      
              targetImage.unlockFocus()
              return targetImage;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-13
        • 2012-07-22
        • 2013-05-13
        • 2020-04-16
        • 2023-03-08
        相关资源
        最近更新 更多