2013-06-10 4 views
0

NSView에 eps 파일을 그리는 데 어려움을 겪고 있습니다. 파일에서 eps 파일을 처음로드하고 drawInRect:으로 그릴 때 이미지가 올바르게 표시됩니다. 그러나 아카이브 파일에서로드 할 때 이미지는 그려지지 않습니다.NSView에서 EPS 데이터를 그리는 방법

복사/붙여 넣기를 수행 할 수있는 더러운 작은 예제를 준비했습니다. 새로운 Cocoa App 프로젝트를 생성하고 이것을 delegate 메소드에 추가하십시오.

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    // Just a sample eps file 
    NSURL *url = [NSURL URLWithString: @"http://embedded.eecs.berkeley.edu/concurrency/latex/figure.eps"]; 
    NSImage *epsImage = [[[NSImage alloc] initWithContentsOfURL: url] autorelease]; 

    // Encode data 
    NSMutableData *mutableData = [[[NSMutableData alloc] init] autorelease]; 
    NSKeyedArchiver *coder = [[[NSKeyedArchiver alloc] initForWritingWithMutableData: mutableData] autorelease]; 
    [coder encodeObject: epsImage forKey: @"image"]; 
    [coder finishEncoding]; 
    NSString *dataFile = [@"~/Desktop/image.data" stringByExpandingTildeInPath]; 
    [mutableData writeToFile: dataFile atomically: YES]; 

    // Decode data 
    NSData *data = [NSData dataWithContentsOfFile: dataFile]; 
    NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData: data]; 
    NSImage *loadedImage = [decoder decodeObjectForKey: @"image"]; 

    // Draw image 
    NSRect rect; 
    rect.origin = NSZeroPoint; 
    rect.size = loadedImage.size; 

    NSView *view = [[NSApp mainWindow] contentView]; 
    [view lockFocus]; 
    [loadedImage drawInRect: rect fromRect: rect operation: NSCompositeSourceOver fraction: 1.0]; 
    [view unlockFocus]; 
} 

첫 번째로드 된 이미지가 제대로 단지 [epsImage drawInRect:...]에 선 [loadedImage drawInRect:...]을 변경립니다 것을 증명합니다.

나는 encodeWithCoder:initWithCoder:을 시뮬레이트하기 위해 여기서 NSKeyedArchiverNSKeyedUnarchiver을 사용하고 있습니다. 따라서 NSImage의 표현이 NSEPSImageRep이고 자원 미리보기의 미리보기가없고 eps 명령으로 만로드 된 사실은 NSView에 올바르게 그려지지 않습니다.

도움을 주시면 감사하겠습니다.

+0

'loadedImage'에서로드 한 후 어떤 NSImageRep이 첨부되어 있습니까? 당신은'loadedImage'와 그것의 이미지 reps에 대한 설명을'NSLog' 할 수 있어야합니다. – gaige

+0

안녕하세요 @gaige, 정확하게 똑같은 데이터 콘텐츠를 가진 NSImageRep (NSEPSImageRep)과 똑같습니다. 미안하다. 전에 언급하지 않았다. 두 이미지 모두 하나의 표현 인 NSEPSImageRep 만 포함합니다. – cocoafan

+0

그건 분명히 이상합니다. 우리는 'NSKeyedArchiver'에서 EPS를 저장 /로드하는 응용 프로그램을 가지고 있으며 문제가 없습니다. 그러나 우리는'NSImage'를 버리고'NSEPSImageRep'을 직접 저장하여 가장 충실한 결과를 얻었습니다 (일단 캐싱이 포함되면 가장 작은 버전과 반대되는 최상의 버전을 얻는 데 문제가있었습니다). 이러한 문제 중 일부는 이전 버전의 OSX에서 사용되었을 수 있습니다.이 코드는 3-4 세입니다. 파일이 EPS가 될 것이라는 것을 알고 있습니까? 이 경우'NSImage' 대신'NSData' 버전을 저장할 수 있습니까? – gaige

답변

2

캐싱이 NSImage에서 작동하는 방식으로 인해, 실제로 형식이 무엇인지 알고있는 경우 실제로 NSImageRep을 잡는 것이 더 효과적이라는 것을 발견했습니다.

코드에서 이미지를 저장하는 가장 신뢰할 수있는 방법은 원본 형식이지만 데이터를 원래 형식으로 저장하거나 NSImageRep에서 데이터를 요청해야합니다. 불행히도 NSImageRep이라는 일반적인 -(NSData*)data 메서드가 없으므로 다양한 유형의 NSImageRep을 확인하고이를 알기에 따라 해당 값을 저장하지 않게되었습니다.

다행히도 로딩은 간단합니다. NSImage::initWithData:은 데이터를 기반으로 유형을 파악합니다.

여기에 오랫동안 저지른 코드가 있습니다. 기본적으로 PDF를 선택한 다음 EPS를 선호하고 이해하지 못하는 항목을 TIFF로 만듭니다. 우리가 NSData*이 있으면

+ (NSData*) dataWithImage:(NSImage*)image kindString:(NSString**)kindStringPtr 
{ 
    if (!image) 
     return nil; 

    NSData *pdfData=nil, *newData=nil, *epsData=nil, *imageData=nil;; 
    NSString *kindString=nil; 
    NSArray *reps = [image representations]; 
    for (NSImageRep *rep in reps) { 
     if ([rep isKindOfClass: [NSPDFImageRep class]]) { 
      // we have a PDF, so save that 
      pdfData = [(NSPDFImageRep*)rep PDFRepresentation]; 
      PDFDocument *doc = [[PDFDocument alloc] initWithData:pdfData]; 
      newData = [doc dataRepresentation]; 
      if (newData && ([newData length]<[pdfData length])) { 
       pdfData = newData; 
      } 
      break; 
     } 
     if ([rep isKindOfClass: [NSEPSImageRep class]]) { 
      epsData = [(NSEPSImageRep*)rep EPSRepresentation]; 
      break; 
     } 
    } 

    if (pdfData) { 
     imageData=pdfData; 
     kindString= @"pdfImage"; 
    } else if (epsData) { 
     imageData=epsData; 
     [email protected]"epsImage"; 
    } else { 
     // make a big copy 
     NSBitmapImageRep *rep0 = [reps objectAtIndex:0]; 
     if ([rep0 isKindOfClass: [NSBitmapImageRep class]]) { 
      [image setSize: NSMakeSize([rep0 pixelsWide], [rep0 pixelsHigh])]; 
     } 

     imageData = [image TIFFRepresentation]; 
     [email protected]"tiffImage"; 
    } 

    if (kindStringPtr) 
     *kindStringPtr=kindString; 
    return imageData; 
} 

, 그것은 디스크 또는 어떤 기록, 키있는 아카이브에 저장 될 수있다. 다시 길에

NSData*의 부하 다음

NSImage *image = [[NSImage alloc] initWithData: savedData]; 

하고 모든 설정해야합니다.

+0

정말 고마워요. 이것은 내가 필요한 것입니다. – cocoafan

관련 문제