Созданный NSBitmapImageRep BMP не может быть прочитан в Windows

У меня есть 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];

Дело в том, что файл BMP можно правильно читать и манипулировать в Mac OSX, но в Windows он просто не загружается, как на этом скриншоте:

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

Если файл открывается с помощью MS Paint (да, MS Paint может открыть его), а затем сохраняется, он будет работать.

Был бы признателен за руку здесь.:)

Заранее спасибо.

1 ответ

Решение

Я думаю, что основная причина, по которой ваш код не работает, заключается в том, что вы создаете свой NSBitmapImageRep с 0 бит на пиксель. Это означает, что ваша репутация изображения будет содержать ровно ноль информации. Вы почти наверняка хотите 32 бит на пиксель.

Тем не менее, ваш код является невероятно запутанным способом получить NSBitmapImageRep из файла изображения на диске. С какой стати вы используете CIImage? Это объект Core Image, предназначенный для использования с фильтрами Core Image и не имеющий здесь никакого смысла. Вы должны использовать NSImage или же CGImageRef,

Ваш метод также плохо назван. Вместо этого оно должно быть названо +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];
}

Вам действительно нужно просмотреть Руководство по рисованию Какао и Руководство по управлению памятью, потому что кажется, что у вас возникают проблемы с некоторыми основными понятиями.

Другие вопросы по тегам