2

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

我尝试使用 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);
 }
4

3 回答 3

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);
}
于 2013-09-17T01:58:19.510 回答
0

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

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

于 2011-02-09T22:01:23.287 回答
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;
}
于 2020-04-06T20:16:39.060 回答