0

.psファイルにepsファイルを描画する問題に苦労していますNSView。ファイルから最初に eps ファイルをロードしdrawInRect:、画像で描画すると、正しく表示されます。ただし、アーカイブ ファイルから読み込むと、画像は描画されません。

コピーして貼り付けて試すことができる、汚い小さな例を用意しました。新しい Cocoa アプリ プロジェクトを作成し、これをデリゲート メソッドに追加します。

- (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];
}

最初に読み込まれた画像が正しく描画されることを証明するには、行[loadedImage drawInRect:...][epsImage drawInRect:...].

NSKeyedArchiverここではandNSKeyedUnarchiverをシミュレートするためにencodeWithCoder:andを使用していますinitWithCoder:。そのため、(リソース フォークからの) プレビューを含まず、純粋に eps コマンドとして読み込まれる表現が正しく描画NSImageされないという事実に注目してください。NSEPSImageRepNSView

どんな助けでも大歓迎です。

4

1 に答える 1

2

でキャッシュが機能する方法により、タイプが何であるかを知っている場合は NSImage、実際に を取得する方が効果的であることがよくあります。NSImageRep

私たちのコードでは、画像を保存する最も信頼できる方法は元の形式であることがわかりましたが、それにはデータを元の形式で別の場所に保存するか、NSImageRep. 残念ながら、 の一般的な-(NSData*)data方法はありませんNSImageRep。そのため、さまざまなタイプの を具体的にチェックし、NSImageRepわかっているものに応じてそれらを保存することになりました。

幸いなことに、ロードは簡単でNSImage::initWithData:、データに基づいて型を判断します。

これを行うための長年のコードを次に示します。基本的に、EPS よりも PDF を優先し、理解できないものはすべて TIFF にします。

+ (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;
        kindString=@"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];
        kindString=@"tiffImage";
    }

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

を取得したらNSData*、キー付きアーカイブに保存したり、ディスクに書き込んだりできます。

戻る途中で、ロードしてNSData*から

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

これで準備完了です。

于 2013-06-10T11:58:42.520 に答える