1

次の方法で作成しているNSBitmapImageRepがあります。

+ (NSBitmapImageRep *)bitmapRepOfImage:(NSURL *)imageURL {
    CIImage *anImage = [CIImage imageWithContentsOfURL:imageURL];
    CGRect outputExtent = [anImage extent];

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

    NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:theBitMapToBeSaved];

    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext: nsContext];
    CGPoint p = CGPointMake(0.0, 0.0);

    [[nsContext CIContext] drawImage:anImage atPoint:p fromRect:outputExtent];

    [NSGraphicsContext restoreGraphicsState];

    return [[theBitMapToBeSaved retain] autorelease];
}

そして、このようにBMPとして保存されます:

NSBitmapImageRep *original = [imageTools bitmapRepOfImage:fileURL];
NSData *converted = [original representationUsingType:NSBMPFileType properties:nil];
[converted writeToFile:filePath atomically:YES];

ここで重要なのは、Mac OSXではBMPファイルを正しく読み取って操作できることですが、Windowsでは、次のスクリーンショットのように、ロードに失敗するだけです。

スクリーンショットhttp://dl.dropbox.com/u/1661304/Grab/74a6dadb770654213cdd9290f0131880.png

ファイルをMSペイントで開いて(はい、MSペイントで開くことができます)、再保存すると、ファイルは機能します。

ここに手をいただければ幸いです。:)

前もって感謝します。

4

1 に答える 1

0

NSBitmapImageRepコードが失敗する主な理由は、ピクセルあたり0ビットでコードを作成していることだと思います。つまり、画像担当者には正確にゼロの情報が含まれます。ほぼ確実に、ピクセルあたり32ビットが必要です。

ただし、コードは、ディスク上の画像ファイルからを取得するための信じられないほど複雑な方法です。NSBitmapImageRep一体なぜあなたはCIImage?これは、CoreImageフィルターで使用するために設計されたCoreImageオブジェクトであり、ここではまったく意味がありません。NSImageまたはを使用する必要がありますCGImageRef

メソッドの名前も適切ではありません。+bitmapRepForImageFileAtURL:代わりに、それが何をしているのかをよりよく示すために、のような名前を付ける必要があります。

また、このコードは意味がありません。

[[theBitMapToBeSaved retain] autorelease]

呼び出しretainてからautorelease何もしません。これは、保持カウントをインクリメントし、すぐに再びデクリメントするためです。

theBitMapToBeSavedを使用して作成したため、リリースする責任がありますalloc。返却中ですので、お電話くださいautorelease。追加retainの呼び出しは、理由もなくリークを引き起こすだけです。

これを試して:

+ (NSBitmapImageRep*)bitmapRepForImageFileAtURL:(NSURL*)imageURL
{
    NSImage* image = [[[NSImage alloc] initWithContentsOfURL:imageURL] autorelease];
    return [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];
}

+ (NSData*)BMPDataForImageFileAtURL:(NSURL*)imageURL
{
    NSBitmapImageRep* bitmap = [self bitmapRepForImageFileAtURL:imageURL];
    return [bitmap representationUsingType:NSBMPFileType properties:nil];
}

いくつかの基本的な概念に問題があるように思われるため、 Cocoa描画ガイドメモリ管理ガイドラインを実際に確認する必要があります。

于 2011-08-24T04:11:27.970 に答える