无法将位图图像复制到可可osx中的粘贴板

时间:2013-12-10 14:15:56

标签: objective-c macos cocoa bitmap

我正在编写一个计算位图图像的图像处理应用程序。它在多个窗口中显示它们,我希望能够将图像复制到粘贴板。每个窗口都有自己的控制器(NSWindowController的子类)和imageView(NSImageView的子类)。

我的代码将成功复制最近显示的窗口中的图像,但是当我从先前显示的窗口复制时,会给出EXC_BAD_ACCESS(代码1)。

窗口控制器中用于设置位图图像的代码如下:

-(void) placeImage:(NSRect) theRect{
    windowRect = theRect;
    [[self window] setTitle:windowName];

    NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc]
                                initWithBitmapDataPlanes: iBitmap.getpixdatap()
                                pixelsWide: iBitmap.getwidth() pixelsHigh: iBitmap.getheight()
                                bitsPerSample: 8 samplesPerPixel: 4 hasAlpha: YES isPlanar:NO
                                colorSpaceName:NSCalibratedRGBColorSpace
                                bytesPerRow: 4*iBitmap.getwidth()
                                bitsPerPixel: 32];

    NSImage* im = [[NSImage alloc] initWithSize:NSMakeSize(iBitmap.getwidth(), iBitmap.getheight())];
    [im addRepresentation:bitmap];

    //NSImage* im = [[NSImage alloc] initByReferencingFile:@"./Contents/Resources/curve.jpg"];

    NSRect rect = NSMakeRect(0, 0, windowRect.size.width,windowRect.size.height-TITLEBAR_HEIGHT);
    [imageView setFrame:rect];
    [imageView setImageScaling:NSScaleToFit];
    [imageView setImage:im];
    [imageView display];

}

对于复制操作:

- (IBAction)copy:sender {
    NSImage *image = [imageView image];
    if (image != nil) {
        NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
        [pasteboard clearContents];
        NSArray *copiedObjects = @[image];
        [pasteboard writeObjects:copiedObjects];
    }
}

如果我用jpeg文件中的图像替换位图图像(上面的placeImage中注释掉的行),那么任何窗口的复制都是成功的。任何建议将不胜感激。

堆栈帧看起来像这样:

0 _platform_memmove $ VARIANT $ Nehalem

1 vImageCopyBuffer

2 Copy_Convert

3 AnyToAnyBiock

4 vImageConvert_AnyToAny

5 ConvertBytesWithRange

6 _CGimagePiuginWriteTIFF

7 CGimageOestinationFinalize

8 + [NSBitmaplmageRep(NSBitmaplmageFileTypeExtensions)representationOflmageRepslnArray:usingType:properties:]

9 - [NStmage TIFFRepresentationUsingCompression:factot:]

10 - [NSimage pasteboardPropertylistForType:]

11 - [NSPasteboard writeObjects:]

12 - [DataWindowController copy:]

13 - [NSApplication sendAction:to:from:]

14 - [NSMenultem _corePerformAction]

15 - [NSCarbonMenulmpl performActionWithHighlightingForltemAtlndex:]

16 - [NSMenu performKeyEquivalent:]

17 - [NSApplication _handleKeyEquivalent:]

18 - [NSApplication sendEvent:]

19 - [NSApplication run]

20 NSApplicationMain

21主

22开始

1 个答案:

答案 0 :(得分:1)

这显然是一个内存管理问题。有用的信息在这里: question 16094748

使用nil初始化位图数据平面,然后显式复制数据似乎可以解决问题。

-(void) placeImage:(NSRect) theRect{
    windowRect = theRect;
    [[self window] setTitle:windowName];

    NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc]
                                initWithBitmapDataPlanes: nil
                                pixelsWide: iBitmap.getwidth() pixelsHigh: iBitmap.getheight()
                                bitsPerSample: 8 samplesPerPixel: 4 hasAlpha: YES isPlanar:NO
                                colorSpaceName:NSCustomColorSpace
                                bytesPerRow: 4*iBitmap.getwidth()  
                                bitsPerPixel: 32];

    memcpy([bitmap  bitmapData], iBitmap.getpixdata(), iBitmap.getheight()*iBitmap.getwidth()*4);

    NSImage* im = [[NSImage alloc] initWithSize:NSMakeSize(iBitmap.getwidth(), iBitmap.getheight())];
    [im addRepresentation:bitmap];

    //NSImage* im = [[NSImage alloc] initByReferencingFile:@"./Contents/Resources/curve.jpg"];

    NSRect rect = NSMakeRect(0, 0, windowRect.size.width,windowRect.size.height-TITLEBAR_HEIGHT);
    [imageView setFrame:rect];
    [imageView setImageScaling:NSScaleToFit];
    [imageView setImage:im];
    [imageView display];

}