Pregunta

Estoy intentando añadir un negro superpuesto sobre algunos de los actuales UIImage (que son de color blanco).He estado tratando de utilizar el siguiente código:

[[UIColor blackColor] set];
[image drawAtPoint:CGPointMake(0, 0) blendMode:kCGBlendModeOverlay alpha:1.0];

Pero no funciona, y estoy bastante seguro de set no debería estar ahí.

¿Fue útil?

Solución

Deberá recortar el contexto a una máscara de imagen y luego rellenarlo con un color sólido:

- (void)drawRect:(CGRect)rect
{
    CGRect bounds = [self bounds];
    [[UIColor blackColor] set];
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClipToMask(context, bounds, [myImage CGImage]);
    CGContextFillRect(context, bounds);
}

Nota: myImage debe ser una variable de instancia que contenga un UIImage. No estoy seguro de si toma la máscara del canal alfa o la intensidad, así que intente con ambos.

Otros consejos

Entonces, para resumir todas las respuestas en una, aquí está el método de inserción que funciona perfectamente desde iOS 6 hasta iOS 11 con todo tipo de imágenes e íconos:

+ (UIImage *)filledImageFrom:(UIImage *)source withColor:(UIColor *)color{

    // begin a new image context, to draw our colored image onto with the right scale
    UIGraphicsBeginImageContextWithOptions(source.size, NO, [UIScreen mainScreen].scale);

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

    // set the fill color
    [color setFill];

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

    CGContextSetBlendMode(context, kCGBlendModeColorBurn);
    CGRect rect = CGRectMake(0, 0, source.size.width, source.size.height);
    CGContextDrawImage(context, rect, source.CGImage);

    CGContextSetBlendMode(context, kCGBlendModeSourceIn);
    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;
}

Actualización: versión Swift 3

func filledImage(source: UIImage, fillColor: UIColor) -> UIImage {

    UIGraphicsBeginImageContextWithOptions(source.size, false, UIScreen.main.scale)

    let context = UIGraphicsGetCurrentContext()
    fillColor.setFill()

    context!.translateBy(x: 0, y: source.size.height)
    context!.scaleBy(x: 1.0, y: -1.0)

    context!.setBlendMode(CGBlendMode.colorBurn)
    let rect = CGRect(x: 0, y: 0, width: source.size.width, height: source.size.height)
    context!.draw(source.cgImage!, in: rect)

    context!.setBlendMode(CGBlendMode.sourceIn)
    context!.addRect(rect)
    context!.drawPath(using: CGPathDrawingMode.fill)

    let coloredImg : UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()

    return coloredImg
}

Acabo de escribir un tutorial que ayudará con esto. Mi enfoque le da una copia de un UIImage, con las alteraciones de color que desee. El enfoque de rpetrich es excelente, pero requiere que estés creando una subclase. Mi enfoque es solo unas pocas líneas de código que se pueden colocar donde sea que las necesite. http://coffeeshopped.com/2010/09/ iphone-how-to-dinámicamente-color-a-uiimage

NSString *name = @"badge.png";
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();

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

Desde iOS 7 hay una solución mucho más simple:

UIImage* im = [UIImage imageNamed:@"blah"];
im = [im imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[[UIColor blackColor] setFill];
[im drawInRect:rect];

Mira este método

 + (UIImage *)imageWithColor:(UIColor *)color andSize:(CGSize)size;
    {
      UIImage *img = nil;

      CGRect rect = CGRectMake(0, 0, size.width, size.height);
      UIGraphicsBeginImageContext(rect.size);
      CGContextRef context = UIGraphicsGetCurrentContext();
      CGContextSetFillColorWithColor(context,
                                     color.CGColor);
      CGContextFillRect(context, rect);
      img = UIGraphicsGetImageFromCurrentImageContext();

      UIGraphicsEndImageContext();

      return img;
    }

Además de la solución de rpetrich (que es genial por cierto, ayúdame magníficamente), también puedes reemplazar la línea CGContextClipToMask con:

    CGContextSetBlendMode(context, kCGBlendModeSourceIn); //this is the main bit!

Es el modo de mezcla SourceIn que hace el trabajo de enmascarar el color por lo que sea que esté en el GetCurrentContext.

Así es como lo haces con Swift 3.0 y usando extensiones para UIImage. Súper simple.

public extension UIImage {
    func filledImage(fillColor: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.size, false, UIScreen.main.scale)

        let context = UIGraphicsGetCurrentContext()!
        fillColor.setFill()

        context.translateBy(x: 0, y: self.size.height)
        context.scaleBy(x: 1.0, y: -1.0)

        context.setBlendMode(CGBlendMode.colorBurn)

        let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
        context.draw(self.cgImage!, in: rect)

        context.setBlendMode(CGBlendMode.sourceIn)
        context.addRect(rect)
        context.drawPath(using: CGPathDrawingMode.fill)

        let coloredImg : UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        return coloredImg
    }
}

Luego, para ejecutarlo, simplemente haz:

let image = UIImage(named: "image_name").filledImage(fillColor: UIColor.red)

-set se utiliza para fijar el color de las subsiguientes operaciones de dibujo, los cuales no incluyen volcados.Sugiero como una primera llamada, mostrando otra (vacío) UIView sobre su UIImageView y la configuración de su color de fondo:

myView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.5];

Obviamente, usted debe utilizar el blanco y alfa valores que usted desea.

Puede hacerlo mediante programación en Swift 4.x de la siguiente manera:

imageView.image = UIImage(named: "imageName")?.withRenderingMode(.alwaysTemplate)
imageView.tintColor = .purple
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top