Frage

Ich versuche, einen schwarzen Overlay über einige aktuelle UIImage ist (das sind weiß) hinzuzufügen. Ich habe versucht, folgenden Code zu verwenden:

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

Aber es funktioniert nicht, und ich bin mir ziemlich sicher, dass Satz nicht da sein soll.

War es hilfreich?

Lösung

Sie wollen den Kontext eine Bildmaske befestigen und dann mit einer Farbe füllen:

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

Hinweis: myImage sollte eine Instanz-Variable sein, die eine UIImage enthält. Ich bin mir nicht sicher, ob sie die Maske aus dem Alphakanal nehmen oder die Intensität so beide versuchen.

Andere Tipps

Also, um es zusammenzufassen, alle Antworten in einem hier ist der Drop-in-Verfahren, das perfekt von iOS 6 den ganzen Weg bis arbeitet mit allen Arten von Bildern und Symbolen iOS 11:

+ (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;
}

Update: Swift 3-Version

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
}

Ich schrieb ein Tutorial, das dabei helfen wird. Mein Ansatz gibt Ihnen eine Kopie eines UIImage, mit den Farbveränderungen, die Sie wollen. rpetrich Ansatz ist groß, aber erfordert, dass Sie eine Unterklasse sind zu schaffen. Mein Ansatz ist nur ein paar Codezeilen, die in überall dort, wo Sie sie brauchen fallen gelassen werden können. http://coffeeshopped.com/2010/09/ iphone-how-to-dynamisch-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;

Seit iOS 7 gibt es eine viel einfachere Lösung:

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

Schauen Sie auf diese Methode

 + (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;
    }

Neben der Lösung von rpetrich (die übrigens toll ist - helfen Sie mir hervorragend), können Sie auch die CGContextClipToMask Linie ersetzen mit:

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

Es ist der SourceIn blendmode, die die Arbeit der Maskierung der Farbe macht durch, was auch immer in der getCurrentContext ist.

Hier ist, wie Sie es mit Swift 3.0 und mit Erweiterungen UIImage. Super einfach.

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
    }
}

Dann ist es zu laufen einfach tun:

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

-set wird verwendet, um die Farbe der nachfolgenden Ziehoperationen einzustellen, die blits nicht enthalten. Ich schlage vor, als erster Anruf, eine andere (leer) UIView über Ihre UIImageView Anzeige und die Hintergrundfarbe einstellen:

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

Natürlich sollten Sie die weißen und Alpha-Werte verwenden, die Sie wollen.

Sie können das tun programmatisch in Swift 4.x auf der nächsten Art und Weise:

imageView.image = UIImage(named: "imageName")?.withRenderingMode(.alwaysTemplate)
imageView.tintColor = .purple
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top