1

NSBitmapImageRepをBMPファイル(Snow Leopard)に保存します。macosで開くと問題ないようです。しかし、それは私のマルチメディアデバイス(インターネットからの任意のBMPファイルを表示することができます)でエラーを起こします。何が悪いのか理解できませんが、ファイルの内部を見ると(macosのクールなhexfiendアプリで)、2つの間違いがあります:

  • ヘッダーのbiHeightパラメーターの値が間違っています:4294966216(hex = C8FBFFFF)ヘッダーのbiWidthパラメーターが正しい:1920
  • ビットマップコンテンツの最初のピクセル(BMP形式の54バイトヘッダーの後)は、元の画像の左上隅に対応します。元のBMPファイルでは、BMP形式で指定されているように、最初に左下隅のピクセルである必要があります。

アプリの完全なワークフローを説明するために、BMP画像をドラッグできるNSImageViewがあります。このビューは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を使用して同じコンテキストでテキストを描画します。

何が悪いのか知っていますか?

4

1 に答える 1

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);
于 2010-04-29T08:12:10.267 に答える