【问题标题】:Emulating NSImage drawInRect:fromRect:operation:fraction with UIImage用 UIImage 模拟 NSImage drawInRect:fromRect:operation:fraction
【发布时间】:2011-01-19 09:11:32
【问题描述】:

我真的需要使用 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);
 }

【问题讨论】:

    标签: iphone macos uiimage porting nsimage


    【解决方案1】:

    这就是我的做法......

    - (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);
    }
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        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;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-06-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-28
          相关资源
          最近更新 更多