문제

나는 NSImage 또는 NSImageCell 내부에 둥근 모서리가 있는 NSTableView.나는 아무것도 할 수 없습니다.내 사용자 정의에 지금까지 가지고 있는 것 중 최고는 다음과 같습니다. NSCell:

- (void)drawInteriorWithFrame:(NSRect)frame inView:(NSView *)controlView { 
  if (thumbnailLink) {
    NSURL *url = [NSURL URLWithString:thumbnailLink];
    if (url) {
        NSRect imageFrame = [self _imageFrameForInteriorFrame:frame];
        NSImage *image = [[NSImage alloc] initWithContentsOfURL:url];
        [image setScalesWhenResized:YES];
        [image setSize:NSMakeSize(IMAGE_HEIGHT, IMAGE_WIDTH)];

        [NSGraphicsContext saveGraphicsState];
        imageFrame = NSInsetRect(imageFrame, 1, 1);
        NSBezierPath *clipPath = [NSBezierPath bezierPathWithRoundedRect:imageFrame cornerRadius:5.0];
        [clipPath setWindingRule:NSEvenOddWindingRule];
        [clipPath addClip];
        [NSGraphicsContext restoreGraphicsState];   
        [image drawInRect:imageFrame fromRect:NSMakeRect(0, 0, 0, 0) operation:NSCompositeSourceIn fraction:1.0];
        [image release];
    }
}
...

이 방법에 대한 아이디어가 있습니까?

도움이 되었습니까?

해결책

이미지를 그릴 때 클립 세트를 유지하고 대신 컨텍스트를 복원해야 합니다.또한 대상 불투명도를 고려하지 않고 이미지를 정상적으로 그리려면 "in" 합성을 사용하는 것이 아니라 "over"를 사용하고 싶다고 생각합니다.다음과 같이 시도해 보세요:

[NSGraphicsContext saveGraphicsState];

NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:imageFrame
                                                     xRadius:5
                                                     yRadius:5];
[path addClip];

[image drawInRect:imageFrame
         fromRect:NSZeroRect
        operation:NSCompositeSourceOver
         fraction:1.0];

[NSGraphicsContext restoreGraphicsState];

다른 팁

+ (NSImage*)roundCorners:(NSImage *)image
{

NSImage *existingImage = image;
NSSize existingSize = [existingImage size];
NSSize newSize = NSMakeSize(existingSize.width, existingSize.height);
NSImage *composedImage = [[[NSImage alloc] initWithSize:newSize] autorelease];

[composedImage lockFocus];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];

NSRect imageFrame = NSRectFromCGRect(CGRectMake(0, 0, 1024, 1024));
NSBezierPath *clipPath = [NSBezierPath bezierPathWithRoundedRect:imageFrame xRadius:200 yRadius:200];
[clipPath setWindingRule:NSEvenOddWindingRule];
[clipPath addClip];

[image drawAtPoint:NSZeroPoint fromRect:NSMakeRect(0, 0, newSize.width, newSize.height) operation:NSCompositeSourceOver fraction:1];

[composedImage unlockFocus];

return composedImage;
}

스위프트 버전 :

func roundCorners(image: NSImage, width: CGFloat = 192, height: CGFloat = 192) -> NSImage {
    let xRad = width / 2
    let yRad = height / 2
    let existing = image
    let esize = existing.size
    let newSize = NSMakeSize(esize.width, esize.height)
    let composedImage = NSImage(size: newSize)

    composedImage.lockFocus()
    let ctx = NSGraphicsContext.currentContext()
    ctx?.imageInterpolation = NSImageInterpolation.High

    let imageFrame = NSRect(x: 0, y: 0, width: width, height: height)
    let clipPath = NSBezierPath(roundedRect: imageFrame, xRadius: xRad, yRadius: yRad)
    clipPath.windingRule = NSWindingRule.EvenOddWindingRule
    clipPath.addClip()

    let rect = NSRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
    image.drawAtPoint(NSZeroPoint, fromRect: rect, operation: NSCompositingOperation.CompositeSourceOver, fraction: 1)
    composedImage.unlockFocus()

    return composedImage
}

// then
roundCorners(image)
roundCorners(image, width: 512, height: 512)

당신이 잘못한 것에 대한 좀 더 많은 정보를 제공하기 위해 :

GSTATE를 저장하고 복원하는 목적은 GSTATE에 대한 변경 사항을 취소 할 수 있어야합니다. 귀하의 경우, 클립을 클리핑 한 후 GSAVE를 복원하면 클립을 실시하십시오. 그렇기 때문에 솔루션 (Rhult가 설명한)이 원하는 것을 그려야하는 것을 그려야합니다. ~ 전에 당신은 gstate를 복원합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top