Созданный NSBitmapImageRep BMP не может быть прочитан в Windows - PullRequest
1 голос
/ 24 августа 2011

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

0 голосов
/ 24 августа 2011

Я думаю, что основная причина неудачного кода заключается в том, что вы создаете 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];
}

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

...