2011-02-28 16 views
5

2 cosas que quiero hacer, que están relacionados:Cómo teñir una imagen/mostrar un color?

  1. Mostrar un bloque de cualquier color. Entonces podría cambiar ese color a otra cosa en cualquier momento.
  2. Tinte un UIImage para que sea de un color diferente. Una superposición de color con alfa rechazado podría funcionar aquí, pero digamos que era una imagen que tenía un fondo transparente y no ocupaba el cuadrado completo de la imagen.

¿Alguna idea?

Respuesta

10

El primero es fácil. Cree un nuevo UIView y configure el color de fondo al color que desee.

El segundo es más difícil. Como mencionaste, puedes colocar una nueva vista encima con la transparencia bajada, pero para hacer que se recorten en los mismos lugares, querrás usar una máscara. Algo como esto:

UIImage *myImage = [UIImage imageNamed:@"foo.png"]; 

UIImageView *originalImageView = [[UIImageView alloc] initWithImage:myImage]; 
[originalImageView setFrame:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f)]; 
[parentView addSubview:originalImageView]; 

UIView *overlay = [[UIView alloc] initWithFrame:[originalImageView frame]]; 

UIImageView *maskImageView = [[UIImageView alloc] initWithImage:myImage]; 
[maskImageView setFrame:[overlay bounds]]; 

[[overlay layer] setMask:[maskImageView layer]]; 

[overlay setBackgroundColor:[UIColor redColor]]; 

[parentView addSubview:overlay]; 

Tenga en cuenta que tendrá que #import <QuartzCore/QuartzCore.h> en el archivo de implementación.

+0

Tuve algunas dificultades para obtener hori zontal centrado en el trabajo. Al principio, estaba agregando superposición como una subvista de una UITableViewCell, y el centrado se perdió cuando la celda se redimensionó. Lo arreglé agregando la superposición como una subvista del campo UILabel dentro de la celda, en lugar de la UITableViewCell. – bneely

+1

También puede intentar agregarlo al 'contentView' de la celda de la vista de tabla. –

2

Una manera fácil de lograr 1 es crear un UILabel o incluso un UIView y cambiar el backgroundColor como lo desee.

Hay una manera de multiplicar colores en lugar de simplemente superponerlos, y eso debería funcionar para 2. Ver this tutorial.

11

Otra opción, sería el uso de métodos categoría en UIImage así ...

// Tint the image, default to half transparency if given an opaque colour. 
- (UIImage *)imageWithTint:(UIColor *)tintColor { 
    CGFloat white, alpha; 
    [tintColor getWhite:&white alpha:&alpha]; 
    return [self imageWithTint:tintColor alpha:(alpha == 1.0 ? 0.5f : alpha)]; 
} 

// Tint the image 
- (UIImage *)imageWithTint:(UIColor *)tintColor alpha:(CGFloat)alpha { 

    // Begin drawing 
    CGRect aRect = CGRectMake(0.f, 0.f, self.size.width, self.size.height); 
    UIGraphicsBeginImageContext(aRect.size); 

    // Get the graphic context 
    CGContextRef c = UIGraphicsGetCurrentContext(); 

    // Converting a UIImage to a CGImage flips the image, 
    // so apply a upside-down translation 
    CGContextTranslateCTM(c, 0, self.size.height); 
    CGContextScaleCTM(c, 1.0, -1.0); 

    // Draw the image 
    [self drawInRect:aRect]; 

    // Set the fill color space 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextSetFillColorSpace(c, colorSpace); 

    // Set the mask to only tint non-transparent pixels 
    CGContextClipToMask(c, aRect, self.CGImage); 

    // Set the fill color 
    CGContextSetFillColorWithColor(c, [tintColor colorWithAlphaComponent:alpha].CGColor); 

    UIRectFillUsingBlendMode(aRect, kCGBlendModeColor); 

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

    // Release memory 
    CGColorSpaceRelease(colorSpace); 

    return img; 
} 
+0

es bueno, pero los píxeles transparentes también se tiñeron – zxcat

+2

1) Para reparar "píxeles transparentes también teñidos", agregue 'CGContextClipToMask (c, aRect, self.CGImage);' antes 'UIRectFillUsingBlendMode'. 2) Para aplicar un tinte verdadero, preservando los valores de imagen, use kCGBlendModeColor. – Wienke

+1

Esto hace que la imagen flippee al revés. Después de obtener el contexto, se deben agregar las siguientes líneas: \t 'CGContextTranslateCTM (c, 0, self.size.height); CGContextScaleCTM (c, 1.0, -1.0); ' – chitza

-1

Prueba este

- (void)viewDidLoad 
    { 
     [super viewDidLoad]; 
     UIView* maskedView = [self filledViewForPNG:[UIImage imageNamed:@"mask_effect.png"] 
               mask:[UIImage imageNamed:@"mask_image.png"] 
              maskColor:[UIColor colorWithRed:.6 green:.2 blue:.7 alpha:1]]; 


     [self.view addSubview:maskedView]; 

    } 

    -(UIView*)filledViewForPNG:(UIImage*)image mask:(UIImage*)maskImage maskColor:(UIColor*)maskColor 
    { 
     UIImageView *pngImageView = [[UIImageView alloc] initWithImage:image]; 
     UIImageView *maskImageView = [[UIImageView alloc] initWithImage:maskImage]; 

     CGRect bounds; 
     if (image) { 
      bounds = pngImageView.bounds; 
     } 
     else 
     { 
      bounds = maskImageView.bounds; 
     } 
     UIView* parentView = [[UIView alloc]initWithFrame:bounds]; 
     [parentView setAutoresizesSubviews:YES]; 
     [parentView setClipsToBounds:YES]; 

     UIView *overlay = [[UIView alloc] initWithFrame:bounds]; 
     [[overlay layer] setMask:[maskImageView layer]]; 
     [overlay setBackgroundColor:maskColor]; 

     [parentView addSubview:overlay]; 
     [parentView addSubview:pngImageView]; 
     return parentView; 
    } 
+0

Explique su respuesta. – hims056

4

Aquí hay otra manera de implementar tintado imagen, sobre todo si ya está usando QuartzCore para otra cosa.

importación QuartzCore:

#import <QuartzCore/QuartzCore.h>  

Crear CALayer transparente y agregarlo como subcapa para la imagen que desea tinte:

CALayer *sublayer = [CALayer layer]; 
[sublayer setBackgroundColor:[UIColor whiteColor].CGColor]; 
[sublayer setOpacity:0.3]; 
[sublayer setFrame:toBeTintedImage.frame]; 
[toBeTintedImage.layer addSublayer:sublayer]; 

Añadir QuartzCore a sus proyectos Lista Marco (si ISN' t ya existe), de lo contrario obtendrá errores de compilación como este:

Undefined symbols for architecture i386: "_OBJC_CLASS_$_CALayer" 
Cuestiones relacionadas