2009-08-03 18 views
34

Chciałbym wiedzieć, jak pokolorować obraz (na przykład zrobić biały .png czerwony). Widziałem różne sugestie, ale nigdy nie było potwierdzenia, że ​​jest to rzeczywiście możliwe. Próbowałem tego:iPhone - Jak kolorować obraz?

-(UIImage *)colorizeImage:(UIImage *)baseImage color:(UIColor *)theColor { 
    UIGraphicsBeginImageContext(baseImage.size); 

    CGContextRef ctx = UIGraphicsGetCurrentContext(); 
    CGRect area = CGRectMake(0, 0, baseImage.size.width, baseImage.size.height); 

    CGContextScaleCTM(ctx, 1, -1); 
    CGContextTranslateCTM(ctx, 0, -area.size.height); 
    CGContextSaveGState(ctx); 
    CGContextClipToMask(ctx, area, baseImage.CGImage); 
    [theColor set]; 
    CGContextFillRect(ctx, area); 
    CGContextRestoreGState(ctx); 
    CGContextSetBlendMode(ctx, kCGBlendModeNormal); 
    CGContextDrawImage(ctx, area, baseImage.CGImage); 
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return newImage; 
} 

myImageView.image = [self colorizeImage:[UIImage imageNamed:@"whiteImage.png"] color:[UIColor redColor]]; 

Ale to nie działa - obraz jest nadal biały na ekranie.

+0

Ale co dokładnie próbujesz zrobić? Czy próbujesz zmienić wszystkie piksele, które są całkowicie białe (RGB (255,255,255)) na czerwony? Czy chcesz tylko dodać czerwony odcień? Czy twój "whiteImage.png" jest właściwie tylko dużym prostokątem wszystkich białych? – Amagrammer

+0

Tak, chcę włączyć białe (lub szare) piksele na czerwono. Przezroczysta część png powinna pozostać przezroczysta. whiteImage.png to nie biały prostokąt - na przykład obraz zwierzęcia. –

+0

Czy istnieje szczególny powód, dla którego nie można po prostu uzyskać czerwonej wersji tego samego obrazu i przełączać między nimi w razie potrzeby? Obrazy dwukolorowe kompresują się bardzo małymi rozmiarami. – Amagrammer

Odpowiedz

0

Jeśli ustawisz kolor tła dla UIImageView na [UIColor redColor], części oryginalnego PNG, które były przezroczyste, staną się czerwone. Alternatywnie możesz spróbować dodać półprzezroczyste UIView z kolorem tła czerwonym jako podglądem widoku obrazu. Spowoduje to dodanie czerwonego zmętnienia do widoku wyświetlającego obraz.

+1

Dzięki, ale chcę pokolorować piksele, które są tylko obecny, a nie cały prostokąt. –

0

Najpierw rysujesz kolor, a następnie rysujesz na nim obraz. O ile obraz nie jest częściowo przezroczysty, spowoduje to całkowite przekroczenie koloru tła. Zalecam najpierw spróbować narysować oryginalny obraz, a następnie nad nim rysować czerwoną czcionką, używając kCGBlendModeHue.

Nie jestem pewien, dlaczego odwracasz i tłumaczysz swój kontekst. Czy twoje zdjęcie jest do góry nogami?

1

Dobra, jak to jest?

W fazie tworzenia zasobów (NIE jest to funkcja dynamiczna podczas działania aplikacji), odwróć schemat kolorów obrazów. Część, która jest teraz biała -> przezroczysta. Część, która jest teraz przezroczysta -> niezależnie od tła strony.

Pod każdym obrazem umieść pusty biały widok o tym samym rozmiarze. Jeśli chcesz zmienić kolor na czerwony, zmień kolor białego pustego widoku na czerwony.

Czy to możliwe?

12

Zmień tryb mieszania na pomnożyć a kod będzie działać:

CGContextSetBlendMode(ctx, kCGBlendModeMultiply); 
+1

+1 Dzięki to zadziałało dla mnie. Zanim dostałem tylko biały kolor, teraz działa dobrze. – HDdeveloper

1

@geek dziecko, daj mi znać, jeśli to pomaga u kolesia ...

// 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); 

// zastąpić "kontekst" z UIGraphicsGetCurrentContext() lub jeśli masz instancję bieżącego kontekstu.

Nadzieję, że pomaga.

63

Ustaw tę kategorię UIImage. Uwzględnia także współczynnik skali w systemie iOS 4.

- (UIImage *)imageWithOverlayColor:(UIColor *)color 
{   
    CGRect rect = CGRectMake(0.0f, 0.0f, self.size.width, self.size.height); 

    if (UIGraphicsBeginImageContextWithOptions) { 
     CGFloat imageScale = 1.0f; 
     if ([self respondsToSelector:@selector(scale)]) // The scale property is new with iOS4. 
      imageScale = self.scale; 
     UIGraphicsBeginImageContextWithOptions(self.size, NO, imageScale); 
    } 
    else { 
     UIGraphicsBeginImageContext(self.size); 
    } 

    [self drawInRect:rect]; 

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSetBlendMode(context, kCGBlendModeSourceIn); 

    CGContextSetFillColorWithColor(context, color.CGColor); 
    CGContextFillRect(context, rect); 

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return image; 
} 

UPDATE - Swift wersja:

func imageWithColor(color: UIColor) -> UIImage { 
    let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height) 
    UIGraphicsBeginImageContextWithOptions(self.size, false, 0.0); 
    drawInRect(rect) 
    let context = UIGraphicsGetCurrentContext() 
    CGContextSetBlendMode(context, .SourceIn) 
    CGContextSetFillColorWithColor(context, color.CGColor) 
    CGContextFillRect(context, rect); 
    let image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    return image 
} 
+0

Dziękuję za to ... dokładnie to, czego potrzebowałem, aby pokolorować tło interfejsu, na podstawie motywu wybranego przez użytkownika. –

+0

To zadziałało także dla mnie :) – DivineDesert

+1

+1 Dzięki to zadziałało dla mnie. Zanim otrzymałem tylko biały kolor, teraz {CGContextSetBlendMode (ctx, kCGBlendModeMultiply);} jak powiedział przez willc2 jego działa dobrze. – HDdeveloper

10

Jako iOS 7 można zabarwić obrazów z jednego koloru jak tak

Objective C

UIImage *image = [UIImage imageNamed:@"myImage.png"]; 
UIImageView *imageView = [[UIImageView alloc]initWithImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]]; 
imageView.tintColor = [UIColor redColor]; 

Swift 3

let image = UIImage(named:"myImage.png")?.withRenderingMode(.alwaysTemplate) 
let imageView = UIImageView(image:image) 
imageView.tintColor = .red 

Będzie barwienia całego obrazu z jednego koloru i zachowania kanał alfa.

+0

to działa pięknie, dziękuję! –

2

Myślę, że najlepszym sposobem, aby pokolorować obraz z iOS7 jest poprzez określenie własności UIImageRenderingModeAlwaysTemplate na obrazie:

myImageView.image = [[UIImage imageNamed:@"myImage"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 

a następnie pokolorować go z tintColor z ImageView

myImageView.tintColor = [UIColor purpleColor]; //Maybe purple is not the best choice ;) 

Myślę, że to jest łatwiejsze (bez kategorii) i oczywiście zoptymalizowane!

Uwaga: jeśli używasz xcassets, można ustawić właściwość oddawania do UIImageRenderingModeAlwaysTemplate w Xcode, jak w tym zrzucie:

UIImageRenderingModeAlwaysTemplate in XCode

1

Krótkie, słodkie i lepiej :)

- (UIImage *)colorizeImage:(UIImage *)image withColor:(UIColor *)color

Zdefiniuj UIColorFromRGB, aby używać kodów kolorów w formacie heksadecymalnym, a następnie zadzwoń pod numer colorizeImage:withColor

#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0] 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    UIImage *imgToColor = [UIImage imageNamed:@"myImage.png"]; 
    imgToColor = [self colorizeImage:imgToColor withColor:UIColorFromRGB(0xff00ff)]; 
    // use normal UIColor or UIColorFromRGB() for hex 
} 

- (UIImage *)colorizeImage:(UIImage *)image withColor:(UIColor *)color 
{ 
    CGRect rect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height); 
    UIGraphicsBeginImageContextWithOptions(image.size, NO, [[UIScreen mainScreen] scale]); 
    [image drawInRect:rect]; 

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSetBlendMode(context, kCGBlendModeSourceIn); 

    CGContextSetFillColorWithColor(context, color.CGColor); 
    CGContextFillRect(context, rect); 

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return newImage; 
} 
Powiązane problemy