5

NSImage にクロスを追加したいのですが、私のコードは次のとおりです。

-(NSSize)convertPixelSizeToPointSize:(NSSize)px
{
    CGFloat displayScale = [[NSScreen mainScreen] backingScaleFactor];
    NSSize res;
    res.width = px.width / displayScale;
    res.height = px.height / displayScale;
    return res;
}

-(void)awakeFromNib
{
    CGFloat scale = [[NSScreen mainScreen] backingScaleFactor];

    NSLog(@"backingScaleFactor : %f",scale);

    NSImage *img = [[[NSImage alloc]initWithContentsOfFile:@"/Users/support/Pictures/cat.JPG"] autorelease];


    NSBitmapImageRep *imgRep = [NSBitmapImageRep imageRepWithData:[img TIFFRepresentation]];
    NSSize imgPixelSize = NSMakeSize([imgRep pixelsWide],[imgRep pixelsHigh]);
    NSSize imgPointSize = [self convertPixelSizeToPointSize:imgPixelSize];
    [img setSize:imgPointSize];

    NSLog(@"imgPixelSize.width: %f , imgPixelSize.height:%f",imgPixelSize.width,imgPixelSize.height);
    NSLog(@"imgPointSize.width: %f , imgPointSize.height:%f",imgPointSize.width,imgPointSize.height);

    [img lockFocus];
    NSAffineTransform *trans = [[[NSAffineTransform alloc] init] autorelease];
    [trans scaleBy:1.0 / scale];
    [trans set];

    NSBezierPath *path = [NSBezierPath bezierPath];     
    [[NSColor redColor] setStroke];
    [path moveToPoint:NSMakePoint(0.0, 0.0)];
    [path lineToPoint:NSMakePoint(imgPixelSize.width, imgPixelSize.height)];
    [path moveToPoint:NSMakePoint(0.0, imgPixelSize.height)];
    [path lineToPoint:NSMakePoint(imgPixelSize.width, 0.0)];

    [path setLineWidth:1];
    [path stroke];
    [img unlockFocus];

    [imageView setImage:img];

    imgRep = [NSBitmapImageRep imageRepWithData:[img TIFFRepresentation]];
    NSData *imageData = [imgRep representationUsingType:NSJPEGFileType properties:nil];
    [imageData writeToFile:@"/Users/support/Pictures/11-5.JPG" atomically:NO];
}

Retina 以外のディスプレイでは、結果は次のようになります。 ここに画像の説明を入力

コンソールが表示されます:

2012-07-06 00:53:09.889 RetinaTest[8074:403] backingScaleFactor : 1.000000
2012-07-06 00:53:09.901 RetinaTest[8074:403] imgPixelSize.width: 515.000000 , imgPixelSize.height:600.000000
2012-07-06 00:53:09.902 RetinaTest[8074:403] imgPointSize.width: 515.000000 , imgPointSize.height:600.000000

ただし、Retina ディスプレイでは (実際の Retina ディスプレイではなく、hidpi モードを使用しました): ここに画像の説明を入力

コンソール:

2012-07-06 00:56:05.071 RetinaTest[8113:403] backingScaleFactor : 2.000000
2012-07-06 00:56:05.083 RetinaTest[8113:403] imgPixelSize.width: 515.000000 , imgPixelSize.height:600.000000
2012-07-06 00:56:05.084 RetinaTest[8113:403] imgPointSize.width: 257.500000 , imgPointSize.height:300.000000

これらの行を省略した場合:

NSAffineTransform *trans = [[[NSAffineTransform alloc] init] autorelease];
            [trans scaleBy:1.0 / scale];
            [trans set];

ここに画像の説明を入力

ただし、[NSAffineTransform scaleBy] を 1.0 に変更すると、正しい結果が得られます

NSAffineTransform *trans = [[[NSAffineTransform alloc] init] autorelease];
        [trans scaleBy:1.0];
        [trans set];

ここに画像の説明を入力

コンソール:

2012-07-06 01:01:03.420 RetinaTest[8126:403] backingScaleFactor : 2.000000
2012-07-06 01:01:03.431 RetinaTest[8126:403] imgPixelSize.width: 515.000000 , imgPixelSize.height:600.000000
2012-07-06 01:01:03.432 RetinaTest[8126:403] imgPointSize.width: 257.500000 , imgPointSize.height:300.000000

誰か説明してくれませんか?hidpi モードは Retina ディスプレイとは異なりますか?

4

2 に答える 2

4

私は答えを見つけたと思います。NSAffineTransform が NSImage のコンテキストに設定されている場合、座標系をピクセル次元 (2 x ポイント次元) に変換します。このように空であっても:

NSAffineTransform *trans = [[[NSAffineTransform alloc] init] autorelease];
[trans set];

それがバグなのか、それとも動作の仕方なのかはわかりません。

于 2012-07-09T12:40:53.437 に答える