2010-04-28 52 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);