3

我的最终目标是用 NSImage 填充任意大小的矩形。我想要:

  1. 填充整个矩形
  2. 保留图像的纵横比
  3. 在保持 1) 和 2) 的同时尽可能多地显示图像
  4. 当无法显示所有图像时,向中心裁剪。

这证明了我正在尝试做的事情。顶部的船的原始图像被绘制成下面各种大小的矩形。

在此处输入图像描述

好的,到目前为止一切顺利。我向 NSImage 添加了一个类别来执行此操作。

@implementation NSImage (Fill)

/**
 * Crops source to best fit the destination
 *
 * destRect is the rect in which we want to draw the image
 * sourceRect is the rect of the image
 */
-(NSRect)scaleAspectFillRect:(NSRect)destRect fromRect:(NSRect)sourceRect
{
    NSSize sourceSize = sourceRect.size;
    NSSize destSize = destRect.size;

    CGFloat sourceAspect = sourceSize.width / sourceSize.height;
    CGFloat destAspect = destSize.width / destSize.height;

    NSRect cropRect = NSZeroRect;

    if (sourceAspect > destAspect) { // source is proportionally wider than dest
        cropRect.size.height = sourceSize.height;
        cropRect.size.width = cropRect.size.height * destAspect;
        cropRect.origin.x = (sourceSize.width - cropRect.size.width) / 2;        
    } else { // dest is proportionally wider than source (or they are equal)
        cropRect.size.width = sourceSize.width;
        cropRect.size.height = cropRect.size.width / destAspect;
        cropRect.origin.y = (sourceSize.height - cropRect.size.height) / 2;
    }

    return cropRect;
}

- (void)drawScaledAspectFilledInRect:(NSRect)rect
{
    NSRect imageRect = NSMakeRect(0, 0, [self size].width, [self size].height);
    NSRect sourceRect = [self scaleAspectFillRect:rect fromRect:imageRect];

    [[NSGraphicsContext currentContext]
         setImageInterpolation:NSImageInterpolationHigh];

    [self drawInRect:rect
            fromRect:sourceRect
           operation:NSCompositeSourceOver
            fraction:1.0 respectFlipped:YES hints:nil];
}

@end

当我想将图像绘制到某个矩形中时,我调用:

[myImage drawScaledAspectFilledInRect:onScreenRect];

工作得很好,除了一个问题。在某些尺寸下,图像看起来很模糊:

在此处输入图像描述

我的第一个想法是我需要在整数像素上绘制,所以我在绘制之前使用了 NSIntegralRect()。没运气。

当我想到它时,我认为这可能是插值的结果。要从较大的图像绘制到较小的绘制矩形 NSImage 必须进行插值。模糊的图像可能只是值映射得不是很好的情况,我们最终会得到一些无法避免的不良伪影。

所以,问题是这样的:我如何选择一个避免这些伪影的最佳矩形?我可以在绘制之前调整绘制矩形或裁剪矩形以避免这种情况,但我不知道如何或何时调整它们。

4

0 回答 0