2011-08-24 128 views
1

读我有一个NSBitmapImageRep,我创建方式如下:NSBitmapImageRep产生BMP不能在Windows

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

的东西在这里是BMP文件可以在Mac OSX下正确读取和操作,但在Windows下,它只是无法加载,就像在此屏幕截图中一样:

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

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

希望能在这里找到一只手。 :)

在此先感谢。

回答

0

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

然而,你的代码是从磁盘上的图像文件获得NSBitmapImageRep难以置信令人费解的方式。为什么你在使用CIImage?这是设计用于核心图像过滤器的核心图像对象,根本没有意义。您应该使用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,因为它看来,您有一些基本概念的麻烦。

+0

您好,首先感谢您的帮助。你是对的,保留] autorelease]根本没有意义。你的代码似乎比我以前的代码好多了。唯一的问题是,BMP的内置文件查看器仍然无法打开,与上面相同的错误。 (你可能还想修复你的第二个方法,以防有人想使用它。你不能调用self,因为对象没有被分配,fileURL应该是imageURL)。 – MegaEduX

+0

你*可以*调用self,因为它是调用另一个类方法的类方法。 –

+0

噢,我想我一直在学习。知道怎么了BMP问题? – MegaEduX