【问题标题】:How to composite several NSImages into one big image?如何将多个 NSImage 合成为一张大图?
【发布时间】:2010-03-04 00:33:30
【问题描述】:

我有一组描述图像名称、大小和 X/Y 位置的对象。集合按“层”排序,所以我可以用某种画家算法合成图像​​。

据此,我可以确定容纳所有图像所需的矩形,所以现在我要做的是:

  • 创建某种缓冲区来保存结果(NS 等效于 iPhoneOS 调用的 UIGraphicsContext。)
  • 将所有图像绘制到缓冲区中。
  • 从缓冲区的合成结果中获取一个新的 NSImage。

在 iPhoneOS 中,这是我想要的代码:

UIGraphicsBeginImageContext (woSize);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    [[UIColor clearColor] set];
    CGContextFillRect(ctx, NSMakeRect(0, 0, woSize.width, woSize.height));
    // draw my various images, here.
    // i.e. Various repetitions of [myImage drawAtPoint:somePoint];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

我正在寻找的是如何在桌面 Cocoa/NS 中做到这一点。

谢谢!

【问题讨论】:

    标签: cocoa image-manipulation nsimage


    【解决方案1】:
    NSImage* resultImage = [[[NSImage alloc] initWithSize:imageSize] autorelease];
    [resultImage lockFocus];
    
    [anotherImage drawAtPoint:aPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
    // Or any of the other about 6 options; see Apple's guide to pick.
    
    [resultImage unlockFocus];
    

    查看Apple's Drawing Guide 以获得更长、更详细的答案。

    【讨论】:

    • 文档说在 Snow-Leopard 中已弃用。 “重要提示:如果您正在编写新代码,或更新旧代码,则应避免使用此方法。而应使用 drawAtPoint:fromRect:operation:fraction: 或 drawInRect:fromRect:operation:fraction: 方法绘制图像. 虽然该方法本身没有被弃用,但它提供的行为不推荐用于一般用途。但我会尝试 drawAtPoint,如果它有效,请给你正确的答案复选标记。 (您可能需要编辑您的答案。)谢谢!
    • 好电话。已编辑。我认为原因是 draw 检查源 rect 而复合没有。只要你确定你传递了一个合理的 rect 就可以了(而且它也快一点),但使用 draw 确实更安全。
    • 是的,lockFocus 是我缺少的东西(如此直观的名称,我无法想象我是如何不去检查文档的!;)谢谢!
    • 注意:如果您使用自己创建的 NSBitmapImageRep 创建 NSImage,那么它会显示您期望的位图,直到您调用 [img lockfocus]。在那之后,似乎您的原始位图缓冲区将不会显示,而只会显示您在图像中绘制的任何内容。我刚刚与 Cocoa 吵过架,但我终于发现了发生了什么。所以如果你想在某个时候做我想做的事,永远不要在你自己的位图上锁定焦点,而是在新图像中绘制你的位图并在其上绘制东西。
    【解决方案2】:
    #import <Cocoa/Cocoa.h>
    
    @interface CompositeView : NSView {
        NSImage *bottom;
        NSImage *top;
    }
    - (IBAction)takeBottomFrom: (id)aView;
    - (IBAction)takeTopFrom: (id)aView;
    @end
    
    #import "CompositeView.h"
    
    @implementation CompositeView
    - (IBAction)takeBottomFrom: (id)aView
    {
        id img = [[aView image] retain];
        [bottom release];
        bottom = img;
        [self setNeedsDisplay: YES];
    }
    
    - (IBAction)takeTopFrom: (id)aView
    {
        id img = [[aView image] retain];
        [top release];
        top = img;
        [self setNeedsDisplay: YES];
    }
    
    - (void)drawRect:(NSRect)rect
    {
        NSCompositingOperation op = 0;
        NSRect bounds = [self bounds];
        NSSize imageSize = bounds.size;
        imageSize.width /= 7;
        imageSize.height /= 2;
    
        NSRect bottomRect = { {0,0}, [bottom size] };
        NSRect topRect = { {0,0}, [top size] };
    
        for (unsigned y=0 ; y<2 ; y++)
        {
            for (unsigned x=0 ; x<7 ; x++)
            {
                NSRect drawRect;
    
                drawRect.origin.y = y * imageSize.height;
                drawRect.origin.x = x * imageSize.width;
                drawRect.size = imageSize;
    
                [bottom drawInRect: drawRect
                          fromRect: bottomRect
                         operation: NSCompositeCopy
                          fraction: 1];
    
                [top drawInRect: drawRect
                       fromRect: topRect
                      operation: op++
                       fraction: 1];
            }
        }
    }
    
    - (id)initWithFrame:(NSRect)frame {
        self = [super initWithFrame:frame];
        if (self) {
            // Initialization code here.
        }
        return self;
    }
    
    @end
    

    【讨论】:

      猜你喜欢
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-31
      • 2013-07-18
      • 2023-04-03
      • 2017-12-25
      相关资源
      最近更新 更多