将未示出的NSViewController导出为JPG

时间:2014-11-27 10:17:35

标签: objective-c macos cocoa core-graphics desktop-application

我正在开发一个桌面应用程序,它从未显示的NSViewController生成图像。 生成的视图有3 NSImageViews,它会在创建后更改内容。

我设法将NSViewController's视图导出到JPG文件,但它永远不会呈现给NSImageView的图像,它会保留在笔尖中设置的图像。另外,如果我没有将背景颜色设置为视图的图层......我得到一个空的结果。

我在这里缺少什么?我想我需要更新NSViewController的视图......但是我该怎么做呢?我不想展示我的NSViewController。

我的代码:

- (IBAction)doExport:(id)sender {
    ExportView *view = [[ExportView alloc] initWithNibName:@"ExportView" bundle:nil];
    [view.pic1 setImage:self.pic1.image];
    [view.pic2 setImage:self.pic2.image];
    [view.pic3 setImage:self.pic3.image];
    [view.icon setImage:self.icon.image];

    // Hardcoding for test
    [view.pic1 setImage:[NSImage imageNamed:@"iPhone 4-Inch Screenshot 1"]];
    [view.pic1 setNeedsLayout:YES];
    [view.pic1 setNeedsDisplay];
    [view.pic1 updateLayer];

    // Setup the image to render
    NSRect imgRect = view.view.frame;
    NSSize imgSize = imgRect.size;

    NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
                                                                    pixelsWide:imgSize.width
                                                                    pixelsHigh:imgSize.height
                                                                 bitsPerSample:8
                                                               samplesPerPixel:4
                                                                      hasAlpha:YES
                                                                      isPlanar:NO
                                                                colorSpaceName:NSDeviceRGBColorSpace
                                                                  bitmapFormat:NSAlphaFirstBitmapFormat
                                                                   bytesPerRow:0
                                                                  bitsPerPixel:0];

    NSGraphicsContext *g = [NSGraphicsContext graphicsContextWithBitmapImageRep:rep];
    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext:g];

    // Set view background color
    CALayer *viewLayer = [CALayer layer];
    [viewLayer setBackgroundColor:[NSColor clearColor].CGColor];
    [view.view setWantsLayer:YES];
    [view.view setLayer:viewLayer];

    // Render
    CGContextRef zCgContextRef = (CGContextRef) [g graphicsPort];
    [[view.view layer] renderInContext:zCgContextRef];

    // Render pic as well, for test
    [view.pic1.layer renderInContext:zCgContextRef];

    // Get the Data for the image
    NSData *exportedData = [rep representationUsingType:NSJPEGFileType properties:nil];

    // Start the savepanel
    NSSavePanel *savepanel = [NSSavePanel savePanel];
    savepanel.title = @"Save chart";

    [savepanel setAllowedFileTypes:[NSArray arrayWithObject:@"jpg"]];

    [savepanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result)
     {
         if (NSFileHandlingPanelOKButton == result)
         {
             NSURL* fileURL = [savepanel URL];

             if ([fileURL.pathExtension isEqualToString:@""])
                 fileURL = [fileURL URLByAppendingPathExtension:@"jpg"];

             [exportedData writeToURL:fileURL atomically:YES];
         }
     }];
}

1 个答案:

答案 0 :(得分:1)

我以一种非常丑陋的方式解决了它。基本上我所做的是将视图添加到contentView并立即将setHidden设置为YES。这将初始化视图。现在我改变了Nib视图的内容。 在将数据呈现到NSData时,我将setHidden更改为NO,生成NSData,然后删除该视图。

最终结果(没有漂亮的代码:()

- (IBAction)doExport:(id)sender {
    ExportView *view = [[ExportView alloc] initWithNibName:@"ExportView" bundle:nil];
    [view.view setHidden:YES];
    [self.window.contentView addSubview:view.view];

    [view.pic1 setImage:self.pic1.image];
    [view.pic2 setImage:self.pic2.image];
    [view.pic3 setImage:self.pic3.image];
    [view.icon setImage:self.icon.image];

    // Setup the image to render
    NSRect imgRect = view.view.frame;
    NSSize imgSize = imgRect.size;

    NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
                                                                    pixelsWide:imgSize.width
                                                                    pixelsHigh:imgSize.height
                                                                 bitsPerSample:8
                                                               samplesPerPixel:4
                                                                      hasAlpha:YES
                                                                      isPlanar:NO
                                                                colorSpaceName:NSDeviceRGBColorSpace
                                                                  bitmapFormat:NSAlphaFirstBitmapFormat
                                                                   bytesPerRow:0
                                                                  bitsPerPixel:0];

    NSGraphicsContext *g = [NSGraphicsContext graphicsContextWithBitmapImageRep:rep];
    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext:g];

    // Set view background color
    CALayer *viewLayer = [CALayer layer];
    [viewLayer setBackgroundColor:[NSColor clearColor].CGColor];
    [view.view setWantsLayer:YES];
    [view.view setLayer:viewLayer];

    [view.view setHidden:NO];

    // Render
    CGContextRef zCgContextRef = (CGContextRef) [g graphicsPort];
    [[view.view layer] renderInContext:zCgContextRef];

    [view.view removeFromSuperview];

    // Get the Data for the image
    NSData *exportedData = [rep representationUsingType:NSJPEGFileType properties:nil];

    // Start the savepanel
    NSSavePanel *savepanel = [NSSavePanel savePanel];
    savepanel.title = @"Save chart";

    [savepanel setAllowedFileTypes:[NSArray arrayWithObject:@"jpg"]];
    [savepanel setNameFieldStringValue:@"Test"];

    [savepanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result)
     {
         if (NSFileHandlingPanelOKButton == result)
         {
             NSURL* fileURL = [savepanel URL];

             if ([fileURL.pathExtension isEqualToString:@""])
                 fileURL = [fileURL URLByAppendingPathExtension:@"jpg"];

             [exportedData writeToURL:fileURL atomically:YES];
         }
     }];
}