2010-03-16 13 views
25

Mam obraz w formacie PNG, który ma nieobsługiwany format pikseli grafiki bitmapowej. Ilekroć próbuję zmienić rozmiar obrazu, CGBitmapContextCreate() dławiki na nieobsługiwanym formacieiPhone: Zmienianie CGImageAlphaInfo obrazu CGImage

otrzymuję następujący błąd (błąd sformatowane dla łatwego czytania):

CGBitmapContextCreate: unsupported parameter combination: 
    8 integer bits/component; 
    32 bits/pixel; 
    3-component colorspace; 
    kCGImageAlphaLast; 
    1344 bytes/row. 

list of supported pixel formats zdecydowanie nie obsługuje tej kombinacji. Wygląda na to, że muszę przerysować obraz i przenieść informacje o kanale alfa do kCGImageAlphaPremultipliedFirst or kCGImageAlphaPremultipliedLast.

Nie mam pojęcia, jak to zrobić.

Nie ma nic niezwykłego w pliku PNG i nie jest on uszkodzony. Działa dobrze w każdym innym kontekście. Napotkałem ten błąd przypadkowo, ale oczywiście moi użytkownicy mogą mieć podobnie sformatowane pliki, więc będę musiał sprawdzić importowane obrazy mojej aplikacji i poprawić ten problem.

Odpowiedz

56

Tak, miałem problemy z 8-bitowym (indeksowanym) .PNGs. Musiałem go przekonwertować na bardziej natywny obraz, aby wykonać operacje graficzne. I w zasadzie zrobił coś takiego:

- (UIImage *) normalize { 

    CGColorSpaceRef genericColorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef thumbBitmapCtxt = CGBitmapContextCreate(NULL, 
                 self.size.width, 
                 self.size.height, 
                 8, (4 * self.size.width), 
                 genericColorSpace, 
                 kCGImageAlphaPremultipliedFirst); 
    CGColorSpaceRelease(genericColorSpace); 
    CGContextSetInterpolationQuality(thumbBitmapCtxt, kCGInterpolationDefault); 
    CGRect destRect = CGRectMake(0, 0, self.size.width, self.size.height); 
    CGContextDrawImage(thumbBitmapCtxt, destRect, self.CGImage); 
    CGImageRef tmpThumbImage = CGBitmapContextCreateImage(thumbBitmapCtxt); 
    CGContextRelease(thumbBitmapCtxt);  
    UIImage *result = [UIImage imageWithCGImage:tmpThumbImage]; 
    CGImageRelease(tmpThumbImage); 

    return result;  
} 
+0

Wygląda dobrze, spróbuję. Nie cierpię robić zbyt wiele, ponieważ obawiam się, że nieumyślnie zniszczę wierność. – TechZen

+0

W końcu udało mi się to przetestować i działa dobrze bez widocznej utraty wierności. – TechZen

+0

Mam problem z powyższym kodem, gdy imageOrientation z UIImage jest inaczej niż OrientationUp - powoduje to obracanie obrazu. Granice obrazu pozostają takie same, ale piksele wewnątrz obrazu są obracane i rozciągane w celu dopasowania do oryginalnych granic. Jest to podobne do tego, co opisano w: http://stackoverflow.com/questions/5973105/image-clicked-from-iphone-in-portrait-mode-gets-rotated-by-90-degree, ale w tym przypadku jest to znormalizuj funkcję, która wydaje się być przyczyną problemu. Ktoś jeszcze to widzi? Jakieś poprawki do tego? – kurtzmarc

5

Oto zaktualizowana wersja metody z Alfons odpowiedzi na uwagę skalę ekranu, a także niektóre głupie błędy z miejscami po przecinku w zmiennoprzecinkowych o wielkości obrazu, jak opisano w zsynchronizowany wypowiedź z oryginalnej odpowiedzi.

SCREEN_SCALE jest makrem, który zwraca wartość 1,0, jeśli skala nie została zdefiniowana, lub niezależnie od tego, jaka jest w rzeczywistości skala urządzenia ([UIScreen mainScreen] .scale).

- (UIImage *) normalize { 

    CGSize size = CGSizeMake(round(self.size.width*SCREEN_SCALE), round(self.size.height*SCREEN_SCALE)); 
    CGColorSpaceRef genericColorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef thumbBitmapCtxt = CGBitmapContextCreate(NULL, 
                 size.width, 
                 size.height, 
                 8, (4 * size.width), 
                 genericColorSpace, 
                 kCGImageAlphaPremultipliedFirst); 
    CGColorSpaceRelease(genericColorSpace); 
    CGContextSetInterpolationQuality(thumbBitmapCtxt, kCGInterpolationDefault); 
    CGRect destRect = CGRectMake(0, 0, size.width, size.height); 
    CGContextDrawImage(thumbBitmapCtxt, destRect, self.CGImage); 
    CGImageRef tmpThumbImage = CGBitmapContextCreateImage(thumbBitmapCtxt); 
    CGContextRelease(thumbBitmapCtxt);  
    UIImage *result = [UIImage imageWithCGImage:tmpThumbImage scale:SCREEN_SCALE orientation:UIImageOrientationUp]; 
    CGImageRelease(tmpThumbImage); 

    return result;  
} 
Powiązane problemy