我有一个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下,它无法加载,就像下面的屏幕截图所示:

screenshot http://dl.dropbox.com/u/1661304/Grab/74a6dadb770654213cdd9290f0131880.png

如果使用MS Paint打开文件(是的,MS Paint可以将其打开),然后重新保存,它将起作用。

在这里将不胜感激。 :)

提前致谢。

最佳答案

我认为您的代码失败的主要原因是您创建的NSBitmapImageRep每像素0位。这意味着您的图像代表将恰好具有零信息。您几乎可以肯定需要每个像素32位。

但是,您的代码是从磁盘上的映像文件获取NSBitmapImageRep的令人难以置信的复杂方法。为什么在地球上使用CIImage?那是一个设计用于Core Image滤镜的Core Image对象,在这里根本没有任何意义。您应该使用NSImageCGImageRef

您的方法名称也不佳。相反,应将其命名为+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 Drawing GuideMemory Management Guidelines,因为您似乎在使用一些基本概念时遇到了麻烦。

10-06 06:30