투명하지 않은 이미지와 마스크 이미지로 투명 이미지 만들기

15566 단어 MacOSXObjective-C
OSX Cocoa에서 투명 이미지와 마스크 이미지를 사용하여 투명 이미지를 만드는 방법입니다.
유일한 방법은 아니라고 생각하지만, 이것만 알 수 있습니다.

등장하는 클래스



NSImage



Cocoa에서 이미지라고 하면 이것.

NSBitmapImageRep



NSImage 내용. NSImageRep의 서브 클래스. 보관할 데이터를 표시하는 방법을 알고 있습니다. 형제에게 PDF용이라든지 여러가지 있다.

CGImageRef



일부 NSImageRep의 내용. C언어다.

CGContextRef



이미지 캔버스 사람. NSGraphicsContext의 친옥. C언어다.

이미지 관련 클래스의 상호 변환



그 전에 이미지 관련 클래스들의 상호 변환 방법

NSImage → NSBitmapImageRep
NSImage *image;
NSData *tiffData = image.TIFFRepresentation;
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:tiffData];

NSBitmapImageRep → CGImageRef
NSBitmapImageRep *imageRep;
CGImageRef imageRef = imageRep.CGImage;

CGImageRef → NSBitmapImageRep
CGImageRef imageRef;
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:imageRef];

NSBitmapImageRep → NSImage
NSBitmapImageRep *imageRep;
NSData *tiffData = imageRep.TIFFRepresentation;
NSImage *image = [[NSImage alloc] initWithData:tiffData];

NSImage → CGImageRef
  • NSImage → NSBitmapImageRep → CGImageRef

  • CGImageRef → NSImage
  • CGImageRef → NSBitmapImageRep → NSImage

  • 투명 이미지 만들기



    그러면 실제로 투명 이미지를 만듭니다.
    
    - (NSImage *)transparentImage:(NSImage *)image maskImage:(NSImage *)mask
    {
        NSBitmapImageRep *maskImageRep = [[NSBitmapImageRep alloc] initWithData:mask.TIFFRepresentation];
    
        NSSize size = image.size;
        NSRect rect = NSMakeRect(0, 0, size.width, size.height);
    
        NSImage *transparentImage = [[NSImage alloc] initWithSize:size];
        [transparentImage lockFocus];
        {
            CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
            CGContextSaveGState(context);
    
            CGContextClipToMask(context, NSRectToCGRect(rect), maskImageRep.CGImage);
    
            [image drawAtPoint:NSZeroPoint
                      fromRect:rect
                     operation:NSCompositeCopy
                      fraction:1.0];
    
            CGContextRestoreGState(context);
        }
        [transparentImage unlockFocus];
    
        return transparentImage;
    }
    
    CGContextClipToMask() 를 사용하여 현재 컨텍스트에 마스크를 설정하고 이미지를 그립니다.

    실제로 이 코드를 사용한 사용한 샘플이 여기입니다.


    응용 예



    NSTextField 의 서브 클래스로서 슈퍼 클래스인 NSTextField 의 렌더링 전에 현재 컨텍스트에 마스크를 설정하는 것으로 페이드 아웃 하는 텍스트 필드를 구축하는 것이 가능합니다.
    @interface HMFadeOutTextField : NSTextField
    @end
    
    @implementation HMFadeOutTextField
    
    - (CGImageRef)maskImageWith:(CGFloat)middle1 middle2:(CGFloat)middle2
    {
        NSRect rect = self.bounds;
        CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray();
        CGContextRef maskContext =
        CGBitmapContextCreate(
                              NULL,
                              rect.size.width,
                              rect.size.height,
                              8,
                              rect.size.width,
                              colorspace,
                              0);
        CGColorSpaceRelease(colorspace);
    
        // Switch to the context for drawing
        NSGraphicsContext *maskGraphicsContext =
        [NSGraphicsContext graphicsContextWithGraphicsPort:maskContext
                                                   flipped:NO];
        [NSGraphicsContext saveGraphicsState];
        [NSGraphicsContext setCurrentContext:maskGraphicsContext];
    
        // Draw the text right-way-up (non-flipped context)
    
        NSGradient *gradient = [[NSGradient alloc] initWithColorsAndLocations:
                                [NSColor whiteColor], 0.0,
                                [NSColor whiteColor], middle1,
                                [NSColor blackColor], middle2,
                                [NSColor blackColor], 1.0,
                                nil];
    
        [gradient drawInRect:rect angle:0.0];
        // Switch back to the window's context
        [NSGraphicsContext restoreGraphicsState];
    
        // Create an image mask from what we've drawn so far
        CGImageRef maskImage = CGBitmapContextCreateImage(maskContext);
    
        CFRelease(maskContext);
    
        return (CGImageRef)CFAutorelease(maskImage);
    }
    
    - (CGImageRef)maskImage
    {
        if(_maskImage) return _maskImage;
    
        _maskImage = [self maskImageWith:0.75 middle2:0.85];
        CFRetain(_maskImage);
    
        return _maskImage;
    }
    
    - (void)drawRect:(NSRect)dirtyRect
    {
        CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
        CGContextSaveGState(context);
        CGContextClipToMask(context, NSRectToCGRect(self.bounds), self.maskImage);
    
        [super drawRect:dirtyRect];
    
        CGContextRestoreGState(context);
    }
    @end
    

    이런 느낌이 듭니다.

    좋은 웹페이지 즐겨찾기