模拟NSImage drawInRect:fromRect:operation:使用UIImage进行分数

时间:2010-02-21 17:11:36

标签: iphone macos uiimage porting nsimage

我真的需要模仿NSImage的drawInRect:fromRect:operation:fraction使用UIImage的行为,我想知道什么是最好的方法或者(更好),如果有人已经这样做并且愿意分享代码。

我尝试使用CGImageCreateWithImageInRect(最后看代码),但我没有得到预期的结果。请注意,代码实际上是在mac上测试它(我现在无法在iPhone上运行整个事情)所以我可能在从NSImage获取CGImage时遇到一些问题

- (void)drawInRect:(CGRect)rect fromRect:(CGRect)fromRect alpha:(float)alpha {
      CGContextRef context;
       CGImageRef originalImageRef;
       CGImageRef subimageRef;

#if ERMac
       context=[[NSGraphicsContext currentContext] graphicsPort];

       CGImageSourceRef source;

       source = CGImageSourceCreateWithData((CFDataRef)[self TIFFRepresentation], NULL);
       originalImageRef =  CGImageSourceCreateImageAtIndex(source, 0, NULL);
       CFRelease(source);
#else
       context=UIGraphicsGetCurrentContext();
       originalImageRef=CGImageRetain([self CGImage]);
#endif

       subimageRef = CGImageCreateWithImageInRect (originalImageRef, fromRect);


       CGContextDrawImage(context, rect, subimageRef);


       if (subimageRef)
           CGImageRelease(subimageRef);
       if (originalImageRef)
           CGImageRelease(originalImageRef);
 }

3 个答案:

答案 0 :(得分:2)

我就是这样做的......

- (void)drawInRect:(CGRect)drawRect fromRect:(CGRect)fromRect operation:(CGBlendMode)blendMode fraction:(CGFloat)alpha
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextClipToRect(context, drawRect);

    CGFloat xScale = (drawRect.size.width/fromRect.size.width);
    CGFloat yScale = (drawRect.size.height/fromRect.size.height);

    CGFloat scale = 1;
    if([self respondsToSelector:@selector(scale)])
    {
        scale = self.scale;
    }

    CGFloat actualWidth = (xScale * self.size.width)*scale;
    CGFloat actualHeight = (yScale * self.size.height)*scale;
    CGFloat xInset = fromRect.origin.x * xScale;
    CGFloat yInset = fromRect.origin.y * yScale;

    // Take care of Y-axis inversion problem by translating the context on the y axis
    CGContextTranslateCTM(context, 0, drawRect.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextDrawImage(context, CGRectMake(-xInset + drawRect.origin.x, -yInset + drawRect.origin.y, actualWidth, actualHeight), self.CGImage);

    CGContextRestoreGState(context);
}

答案 1 :(得分:0)

UIImage有drawInRect:blendMode:alpha:。提取UIImage的子矩形的一个简单技巧是绘制到目标上下文,该目标上下文是您要提取的矩形的大小,向上和向左调整绘制图像的原点,使右侧部分落入目标上下文。

CGImage也是一种很好的方法,但是你可能会遇到在iPhone上翻转坐标系的问题。一个简单的解决方案是将CGImage包装成UIImage并绘制它,因为UIImage知道要绘制的方式。

答案 2 :(得分:0)

NSImage类别方法示例以及我的iOS移植端口:

-(NSImage*)getSubimageWithRect:(CGRect)rect {
    NSBitmapImageRep *rep = [[NSBitmapImageRep alloc]
                         initWithBitmapDataPlanes:NULL
                         pixelsWide:rect.size.width
                         pixelsHigh:rect.size.height
                         bitsPerSample:8
                         samplesPerPixel:4
                         hasAlpha:YES
                         isPlanar:NO
                         colorSpaceName:NSDeviceRGBColorSpace
                         bytesPerRow:0
                         bitsPerPixel:0];

    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:rep]];
    [self drawInRect:CGRectMake(0, 0, rect.size.width, rect.size.height) fromRect:rect operation:NSCompositingOperationCopy fraction:1.0];
    [NSGraphicsContext restoreGraphicsState];

    NSImage *newImage = [[NSImage alloc] initWithSize:rect.size];
    [newImage addRepresentation:rep];
    return newImage;
}

iOS代码:

-(UIImage*)getSubimageWithRect:(CGRect)rect {
    CGFloat width = rect.size.width;
    CGFloat height = rect.size.height;
    CGContextRef context = CGBitmapContextCreate(NULL, width, height,
8, 4*width, CGColorSpaceCreateDeviceRGB(),
kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault);

    CGContextDrawImage(context, CGRectMake(-rect.origin.x, -rect.origin.y, self.size.width, self.size.height), self.CGImage);
    CGImageRef ref = CGBitmapContextCreateImage(context);

    UIImage *newImage = [UIImage imageWithCGImage:ref];

    CGImageRelease(ref);
    CGContextRelease(context);

    return newImage;
}