2010-11-09 8 views
5

Moja aplikacja na iPhone'a ma niestandardowe UITableViewCell s, z których każda posiada ikonę. W stanie normalnej komórki ikony są czarne z przezroczystym tłem. Zamiast zawiązywania drugiego zestawu odwróconych ikon z aplikacją dla podświetlonego stanu (biały na przezroczystym tle) chciałbym odwrócić te ikony w locie za pomocą Core Graphics za każdym razem, gdy użytkownik dotknie odpowiedniej komórki tabeli.Próba dynamicznego kolorowania przezroczystych UIImages, ale nadal uzyskują rozmyte wyniki. Co ja robię źle?

Znalazłem kilka innych odpowiedzi związanych z nakładaniem UIImage z kolorem lub ponownym kolorowaniem UIImage s, ale wszystkie te techniki dają mi niewyraźny wynik (patrz poniżej). Próbowałem już wszystkich typów, a także ręcznie obliczałem dokładniejszą maskę (być może zrobiłem to niepoprawnie), ale wydaje mi się, że półprzezroczyste piksele wokół krawędzi ikon powodują, że ich nieprzezroczystość jest zakorkowana lub w zasadzie są upuszczenie - dając chropowaty/niewyraźny wygląd. Brakuje mi tego, co robię źle.

Nie jest to również opcja zmiany wszystkich moich ikon, które są po prostu czyste czarno-białe bez przezroczystości - potrzebuję ikon, aby usiąść na przezroczystym tle, aby można je było nałożyć na inne elementy interfejsu użytkownika dobrze.

Kod (dzięki uprzejmości Chadwick Wood), którego używam do odwrócenia ikony (nazywam tę metodę na każdym z moich oryginalnych ikon i przekazuję w [UIColor whiteColor] jako drugi argument) i przykładowym wyjściu (na iPhonie 4 z iOS 4.1) znajduje się poniżej (zignoruj ​​niebieskie tło podświetlonego obrazu - jest to podświetlone tło wybranej komórki tabeli).

Każda pomoc jest bardzo doceniana.

Przykład Wejście & wyjściowa:

Icon before & after programmatic recoloring.

@implementation UIImage(FFExtensions) 

+ (UIImage *)imageNamed:(NSString *)name withColor:(UIColor *)color { 

// load the image 
UIImage *img = [UIImage imageNamed:name]; 

// begin a new image context, to draw our colored image onto 
UIGraphicsBeginImageContext(img.size); 

// get a reference to that context we created 
CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextSetInterpolationQuality(context, kCGInterpolationHigh); 

// set the fill color 
[color setFill]; 

// translate/flip the graphics context (for transforming from CG* coords to UI* coords 
CGContextTranslateCTM(context, 0, img.size.height); 
CGContextScaleCTM(context, 1.0, -1.0); 

// set the blend mode to color burn, and the original image 
CGContextSetBlendMode(context, kCGBlendModeMultiply); 
CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height); 
//CGContextDrawImage(context, rect, img.CGImage); 

// set a mask that matches the shape of the image, then draw (color burn) a colored rectangle 
CGContextClipToMask(context, rect, img.CGImage); 
CGContextAddRect(context, rect); 
CGContextDrawPath(context,kCGPathFill); 


// generate a new UIImage from the graphics context we drew onto 
UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

//return the color-burned image 
return coloredImg; 
} 

@end 
+0

Jaki jest rozmiar obrazu i jak go rysujesz? Czy istnieje dodatkowy etap skalowania, czy też obraz jest rysowany na nieintegralnym pikselu? –

+0

Nie jest rozmazany, ma niższą rozdzielczość. Jeśli porównasz rozmiary pikseli obrazów CGImages, okaże się, że są różne. Nie wiem wystarczająco dużo Cocoa Touch, aby powiedzieć, jak to naprawić, ale to jest problem, który musisz rozwiązać. –

+0

@Steven Rozmiar oryginalnego obrazu, który jest kolorowy, zależy od urządzenia. Jest to albo 52px (wyświetlacz Retina) albo 26px (iPhone 3G/3GS). Zamieszczony przeze mnie przykład to obraz widziany na iPhonie 4. Z obrazu wynika, że ​​skalowanie dzieje się w jakiś sposób, ale nie jestem pewien dlaczego. Celowo zostawiam .png/@ 2x.png z argumentu name dla tej funkcji, aby + imagedNamed: (w pierwszym wierszu funkcji) wybrał poprawny plik źródłowy w zależności od urządzenia. –

Odpowiedz

5

Dzięki Peter & obserwacji Stevena że rozdzielczość obrazu wyjściowego zdawała się być niższa niż wejście, zdałem sobie sprawę, że nie stanowiło współczynnik skali ekranu podczas tworzenia mojego kontekstu obrazu.

Zmiana linię:

UIGraphicsBeginImageContext(img.size); 

do

UIGraphicsBeginImageContextWithOptions(img.size, NO, [UIScreen mainScreen].scale); 

rozwiązuje problem.

+2

Albo, jeszcze łatwiej: Wystarczy podać 0.0 jako ostatni parametr do 'UIGraphicsBeginImageContextWithOptions()'. Z [dokumentacji] (http://developer.apple.com/library/ios/documentation/uikit/reference/UIKitFunctionReference/Reference/reference.html # // apple_ref/c/func/UIGraphicsBeginImageContextWithOptions): "Jeśli podasz wartość 0.0, współczynnik skali zostanie ustawiony na współczynnik skali głównego ekranu urządzenia." –

Powiązane problemy