2011-11-27 86 views
1

我試圖做如下的批處理:如何將NSImageView圖層保存到磁盤上的PNG?

  1. 加載圖像
  2. 規模也
  3. 添加圓角的邊框給它
  4. 保存新 形象PNG

到目前爲止,我想出了這個:

CGPoint center = CGPointMake(self.window.frame.size.width/2., self.window.frame.size.height/2.); 
     [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh]; 
     NSImage * newThumbnail = [[NSImage alloc] initWithData:[NSData dataWithContentsOfURL:[files objectAtIndex:0]]]; 
     NSImageView *imageView = [[NSImageView alloc] initWithFrame:CGRectMake(center.x - (57/2.), center.y - (80/2.), 57, 80)]; 
     [imageView setWantsLayer:YES]; 

     imageView.layer.borderColor = [[NSColor blackColor] CGColor]; 
     imageView.layer.cornerRadius = 4; 
     imageView.layer.masksToBounds = YES; 
     imageView.layer.borderWidth = 1.0; 
     imageView.image = newThumbnail; 

現在我想我錯過了讓圖層重新融入某種情境? 可能類似於[imageView.layer drawInContext: some context (NS o CG?)];並將該上下文保存到磁盤。但我很困惑,:

什麼情況下,

是否從上下文中去NSData的磁盤,

,或者如果我保存在什麼地方需要一箇中間圖像。基本上,CALayers和CGLayers和NS對象和UI對象之間(我知道我在OS X可可在這裏,它沒有UIKit,我也沒有使用CG的東西)我不知道如何轉向以上變成了png。

回答

2

根本不應該使用視圖,因爲您不需要顯示到屏幕。您應該使用離屏位圖(NSBitmapImageRep)並使用繪圖命令繪製圖像。

在Cocoa中繪圖有兩種選擇。最簡單的方法是使用各種Cocoa繪圖類,例如NSBezierPath和朋友。另一種選擇是功能更強大但更低級和複雜的Quartz API,它們不是面向對象的,而是使用C函數語法。

下面是如何你想使用什麼可可圖紙做了一個例子:

NSImage* anImage = [NSImage imageNamed:@"Lenna.tiff"]; //or some other source 

//create a bitmap at a specific size 
NSRect offscreenRect = NSMakeRect(0.0, 0.0, 250.0, 250.0); 
NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil 
                 pixelsWide:offscreenRect.size.width 
                 pixelsHigh:offscreenRect.size.height 
                bitsPerSample:8 
                samplesPerPixel:4 
                 hasAlpha:YES 
                 isPlanar:NO 
                colorSpaceName:NSCalibratedRGBColorSpace 
                bitmapFormat:0 
                 bytesPerRow:(4 * offscreenRect.size.width) 
                bitsPerPixel:32]; 

//save the current graphics context and lock focus on the bitmap 
NSGraphicsContext* originalContext = [NSGraphicsContext currentContext]; 
[NSGraphicsContext setCurrentContext:[NSGraphicsContext 
             graphicsContextWithBitmapImageRep:bitmap]]; 
[NSGraphicsContext saveGraphicsState]; 

//clear the image rep. This is faster than filling with [NSColor clearColor]. 
unsigned char *bitmapData = [bitmap bitmapData]; 
if (bitmapData) 
    bzero(bitmapData, [bitmap bytesPerRow] * [bitmap pixelsHigh]); 

//create the border path 
CGFloat borderWidth = 2.0; 
CGFloat cornerRadius = 14.0; 
NSRect borderRect = NSInsetRect(offscreenRect, borderWidth/2.0, borderWidth/2.0); 
NSBezierPath* border = [NSBezierPath bezierPathWithRoundedRect:borderRect xRadius:cornerRadius yRadius:cornerRadius]; 
[border setLineWidth:borderWidth]; 

//set the border as a clipping path 
[NSGraphicsContext saveGraphicsState]; 
[border addClip]; 

//scale and draw the image 
[anImage setSize:offscreenRect.size]; 
[anImage drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; 
[NSGraphicsContext restoreGraphicsState]; 

//set the border color 
[[NSColor blackColor] set]; 

//draw the border 
[border stroke]; 

//restore the original graphics context 
[NSGraphicsContext restoreGraphicsState]; 
[NSGraphicsContext setCurrentContext:originalContext]; 

//get PNG data from the image rep 
NSData* pngData = [bitmap representationUsingType:NSPNGFileType properties:nil]; 
NSError* error; 
if(![pngData writeToURL:[NSURL fileURLWithPath:[NSHomeDirectory() stringByAppendingPathComponent:@"test.png"]] options:NSDataWritingAtomic error:&error]) 
{ 
    NSLog(@"%@",error); 
} 
+0

其實我可能會去的石英的方法,因爲它更像是OpenGL的哪個我更舒服。但這種方式也起作用。謝謝! – SaldaVonSchwartz