kakao - NSBitmapImageRep genereret BMP kan ikke læses på Windows

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har en NSBitmapImageRep, som jeg opretter på følgende måde:


+ (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];
}


Og bliver gemt som BMP på denne måde:


NSBitmapImageRep *original = [imageTools bitmapRepOfImage:fileURL];
NSData *converted = [original representationUsingType:NSBMPFileType properties:nil];
[converted writeToFile:filePath atomically:YES];


Sagen her er, at BMP-filen kan læses og manipuleres korrekt under Mac OSX, men under Windows bliver det bare ikke at indlæse, ligesom i dette skærmbillede:


screenshot http://dl.dropbox.com/u/1661304/Grab/74a6dadb770654213cdd9290f0131880.png[17]


Hvis filen åbnes med MS Paint (ja, MS Paint kan åbne den) og derefter resaved, men det vil fungere.


Vil sætte pris på en hånd her. :)


Tak på forhånd.

Bedste reference


Jeg tror, ​​at hovedårsagen til din kode ikke er, at du opretter din NSBitmapImageRep med 0 bits pr pixel. Det betyder, at din billedrepræsentant vil have nøjagtigt nulinformation i den. Du vil næsten helt sikkert have 32 bits pr pixel.


Din kode er dog en utroligt forvrænget måde at opnå en NSBitmapImageRep fra en billedfil på disken. Hvorfor i verden bruger du en CIImage? Det er et Core Image-objekt designet til brug med Core Image-filtre og giver ingen mening her overhovedet. Du skal bruge en NSImage eller CGImageRef.


Din metode er også dårligt navngivet. Det skal i stedet hedde noget som +bitmapRepForImageFileAtURL: for bedre at angive, hvad det gør.


Også denne kode giver ingen mening:


[**theBitMapToBeSaved retain] autorelease]


At ringe retain og derefter autorelease gør intet, fordi alt det gør i trin, beholder tællingen og derefter formindsker det igen med det samme.


Du er ansvarlig for at frigive theBitMapToBeSaved fordi du oprettede den ved hjælp af alloc. Da den bliver returneret, skal du ringe autorelease på den. Din yderligere retain opkald forårsager bare en lækage uden grund.


Prøv dette:


+ (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];
}


Du skal virkelig gennemgå Cocoa Drawing Guide og retningslinjerne for Memory Management, fordi det ser ud til, at du har problemer med nogle grundlæggende begreber. [18] [19]