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

1つの問題を除いて、非常にうまく機能します。特定のサイズでは、画像がかなりぼやけて見えます。

ここに画像の説明を入力

最初に考えたのは、整数ピクセルで描画する必要があるということでした。そのため、描画する前に NSIntegralRect() を使用しました。運がない。

考えてみると、おそらく補間の結果だと思いました。大きな画像から小さな描画四角形に描画するには、NSImage を補間する必要があります。画像がぼやけているのは、値が適切にマッピングされておらず、避けられない望ましくないアーティファクトが発生した場合にすぎない可能性があります。

問題はこれです: これらのアーティファクトを回避する最適な四角形をどのように選択すればよいでしょうか? これを避けるために、描画する前に描画四角形または切り抜き四角形を調整できますが、いつどのように調整すればよいかわかりません。

4

0 に答える 0