2010-04-28 55 views
1

我将NSBitmapImageRep保存为BMP文件(Snow Leopard)。当我在macos上打开它时似乎没问题。但它会在我的多媒体设备上发生错误(它可以显示来自Internet的任何BMP文件)。我无法弄清楚什么是错的,但是当我看到里面的文件(与MacOS的清凉hexfiend应用程序),错误的两两件事:将NSBitmapImageRep另存为NSBMPFileType文件。错误的BMP标题和位图内容

  • 头具有的biHeight参数错误值:4294966216(十六进制= C8FBFFFF) 头部具有正确的双宽度参数:1920
  • 位图内容中的第一个像素(位于BMP格式的54个字节标头之后)对应于原始图像的左上角。在原始的BMP文件中,如BMP格式所指定的,它应该是第一个左下角的像素。

为了解释我的应用程序的完整工作流程,我有一个NSImageView,我可以拖动BMP图像。该视图绑定到NSImage。 拖动后&我有一个行动来保存这个图像(与一些文字在它上面)到一个BMP文件。

下面是保存新BMP文件代码:

CGColorSpaceRefcolorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 
CGContextRefcontext = CGBitmapContextCreate(NULL, (int)1920, (int)1080, 8, 4*(int)1920, colorSpace, kCGImageAlphaNoneSkipLast); 

[duneScreenViewdrawBackgroundWithDuneFolder:self inContext:context inRect:NSMakeRect(0,0,1920,1080) needScale:NO]; 
if(folderType==DXFolderTypeMovie) { 

    [duneScreenViewdrawSynopsisContentWithDuneFolder:self inContext:context inRect:NSMakeRect(0,0,1920,1080) withScale:1.0]; 
} 


CGImageRef backgroundImageRef = CGBitmapContextCreateImage(context); 
NSBitmapImageRep*bitmapBackgroundImageRef = [[NSBitmapImageRepalloc] initWithCGImage:backgroundImageRef]; 


NSData*data = [destinationBitmap representationUsingType:NSBMPFileType properties:nil]; 
[data writeToFile:[NSStringstringWithFormat:@"%@/%@", folderPath,backgroundPath] atomically: YES]; 

的duneScreenViewdrawSynopsisContentWithDuneFolder方法使用CGContextDrawImage绘制图像。 duneScreenViewdrawSynopsis方法使用CoreText在相同的上下文中绘制一些文本。

你知道怎么回事吗?

回答

1

我刚刚注册了一个openid帐户,所以我不能编辑自己的问题。我找到了解决这个问题的方法,并想发布我的解决方案。

有2个问题:在BMP头

  • 错biHeight参数
  • 位图中的内容垂直翻转数据(开始与向下左上角的地方左上角第一)

对于biHeight参数,我更换了biHeight字节到良好的价值(1080我的形象)

对于翻转的问题,我只是翻转内容位图字节中的所有行。

可能这不是最优雅的解决方案,但它工作正常。如果您有其他解决方案,请告诉我。

下面的代码:

intwidth = 1920; 
intheight = 1080; 

CGColorSpaceRefcolorSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRefcontext = CGBitmapContextCreate(NULL, (int)width, (int)height, 8, 4* (int)width, colorSpace, kCGImageAlphaNoneSkipLast); 

[duneScreenViewdrawBackgroundWithDuneFolder:selfinContext:context inRect:NSMakeRect(0,0,width,height) needScale:NO]; 
if(folderType==DXFolderTypeMovie) { 

    [duneScreenViewdrawSynopsisContentWithDuneFolder:selfinContext:context inRect:NSMakeRect(0,0,width,height) withScale:1.0]; 
} 

CGImageRefbackgroundImageRef = CGBitmapContextCreateImage(context); 

NSBitmapImageRep*bitmapBackgroundImageRef = [[NSBitmapImageRepalloc] initWithCGImage:backgroundImageRef]; 

NSData*data = [bitmapBackgroundImageRef representationUsingType:NSBMPFileTypeproperties:nil]; 

NSMutableData*mutableData = [[NSMutableDataalloc] init]; 

intbitmapBytesOffset = 54; 

//headers 
[mutableData appendData:[data subdataWithRange:NSMakeRange(0,bitmapBytesOffset)]]; 

//bitmap data 
intlineIndex=height-1; 

while(lineIndex>=0) { 

    [mutableData appendData:[data subdataWithRange:NSMakeRange(bitmapBytesOffset+lineIndex*width*3,width*3)]]; 

    lineIndex--; 
} 

//force biHeight header parameter to 1080 
NSString*biHeightString = @"\x38\x04\x00\x00"; 
NSData*biHeightData = [biHeightString dataUsingEncoding:NSUTF8StringEncoding]; 
[mutableData replaceBytesInRange:NSMakeRange(22,4) withBytes:[biHeightData bytes]]; 

[mutableData writeToFile:[NSStringstringWithFormat:@"%@/%@", folderPath,backgroundPath] atomically: YES]; 

[mutableData release]; 


CGImageRelease(backgroundImageRef); 
[bitmapBackgroundImageRef release]; 
CGContextRelease(context); 
CGColorSpaceRelease(colorSpace);