Update: Hier ist ein Gist für eine Swift UIColor Erweiterung mit dem Code unten.
Wenn Sie ein Graustufenbild haben und möchten, dass Weiß zur Tönungsfarbe wird , kCGBlendModeMultiply
ist dies der richtige Weg. Mit dieser Methode können Sie keine Glanzlichter erzielen, die heller als Ihre Tönungsfarbe sind.
Im Gegenteil, wenn Sie entweder einen haben Nicht-Graustufenbild , ODER Sie Highlights und Schatten , die erhalten werden sollen, der Mischmodus kCGBlendModeColor
ist der Weg zu gehen. Weiß bleibt weiß und Schwarz bleibt schwarz, wenn die Helligkeit des Bildes erhalten bleibt. Dieser Modus dient nur zum Abtönen. Er entspricht dem Ebenenüberblendungsmodus von Photoshop Color
(Haftungsausschluss: Es können leicht abweichende Ergebnisse auftreten).
Beachten Sie, dass das Abtönen von Alpha-Pixeln weder in iOS noch in Photoshop ordnungsgemäß funktioniert - halbtransparente schwarze Pixel bleiben nicht schwarz. Ich habe die Antwort unten aktualisiert, um dieses Problem zu umgehen. Es hat ziemlich lange gedauert, es herauszufinden.
Sie können kCGBlendModeSourceIn/DestinationIn
stattdessen auch einen der Mischmodi verwenden CGContextClipToMask
.
Wenn Sie eine erstellen möchten, UIImage
kann jeder der folgenden Codeabschnitte von folgendem Code umgeben sein:
UIGraphicsBeginImageContextWithOptions (myIconImage.size, NO, myIconImage.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, myIconImage.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGRect rect = CGRectMake(0, 0, myIconImage.size.width, myIconImage.size.height);
UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Hier ist der Code zum Abtönen eines transparenten Bildes mit kCGBlendModeColor
:
CGContextSetBlendMode(context, kCGBlendModeNormal);
[[UIColor blackColor] setFill];
CGContextFillRect(context, rect);
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextDrawImage(context, rect, myIconImage.CGImage);
CGContextSetBlendMode(context, kCGBlendModeColor);
[tintColor setFill];
CGContextFillRect(context, rect);
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, rect, myIconImage.CGImage);
Wenn Ihr Bild keine halbtransparenten Pixel enthält, können Sie dies auch umgekehrt tun mit kCGBlendModeLuminosity
:
CGContextSetBlendMode(context, kCGBlendModeNormal);
[tintColor setFill];
CGContextFillRect(context, rect);
CGContextSetBlendMode(context, kCGBlendModeLuminosity);
CGContextDrawImage(context, rect, myIconImage.CGImage);
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, rect, myIconImage.CGImage);
Wenn Sie sich nicht für die Leuchtkraft interessieren, da Sie nur ein Bild mit einem Alphakanal haben, das mit einer Farbe getönt werden sollte, können Sie dies effizienter tun:
CGContextSetBlendMode(context, kCGBlendModeNormal);
[tintColor setFill];
CGContextFillRect(context, rect);
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, rect, myIconImage.CGImage);
oder umgekehrt:
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextDrawImage(context, rect, myIconImage.CGImage);
CGContextSetBlendMode(context, kCGBlendModeSourceIn);
[tintColor setFill];
CGContextFillRect(context, rect);
Habe Spaß!
Ich hatte den größten Erfolg mit dieser Methode, weil die anderen, die ich ausprobierte, bei bestimmten Farbkombinationen verzerrte Farben für halbtransparente Pixel verursachten. Dies sollte auch auf der Leistungsseite etwas besser sein.
+ (UIImage *) imageNamed:(NSString *) name withTintColor: (UIColor *) tintColor { UIImage *baseImage = [UIImage imageNamed:name]; CGRect drawRect = CGRectMake(0, 0, baseImage.size.width, baseImage.size.height); UIGraphicsBeginImageContextWithOptions(baseImage.size, NO, 0); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextTranslateCTM(context, 0, baseImage.size.height); CGContextScaleCTM(context, 1.0, -1.0); // draw original image CGContextSetBlendMode(context, kCGBlendModeNormal); CGContextDrawImage(context, drawRect, baseImage.CGImage); // draw color atop CGContextSetFillColorWithColor(context, tintColor.CGColor); CGContextSetBlendMode(context, kCGBlendModeSourceAtop); CGContextFillRect(context, drawRect); UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return tintedImage; }
quelle
CGContextSetBlendMode(context, kCGBlendModeNormal); CGContextDrawImage(context, rect, self.CGImage); CGContextSetBlendMode(context, kCGBlendModeSourceIn); [color setFill]; CGContextFillRect(context, rect);
Nach dem Durchsuchen besteht die beste Lösung, die ich bisher gefunden habe, darin, eine Kombination aus Mischmodus und Schnittmaske zu verwenden, um ein transparentes PNG einzufärben / zu färben:
CGContextSetBlendMode (context, kCGBlendModeMultiply); CGContextDrawImage(context, rect, myIconImage.CGImage); CGContextClipToMask(context, rect, myIconImage.CGImage); CGContextSetFillColorWithColor(context, tintColor); CGContextFillRect(context, rect);
quelle
Mit kCGBlendModeOverlay kann ich Ergebnisse erzielen, die dem Farbton in der Apple-Navigationsleiste sehr nahe kommen. Ich habe eine exzellente @ fabb-Antwort genommen und den @ omz-Ansatz in diesem Beitrag kombiniert. Https://stackoverflow.com/a/4684876/229019 Ich bin mit dieser Lösung gekommen, die die erwarteten Ergebnisse enthält:
- (UIImage *)tintedImageUsingColor:(UIColor *)tintColor; { UIGraphicsBeginImageContextWithOptions (self.size, NO, [[UIScreen mainScreen] scale]); CGContextRef context = UIGraphicsGetCurrentContext(); CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height); // draw original image [self drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0f]; // tint image (loosing alpha). // kCGBlendModeOverlay is the closest I was able to match the // actual process used by apple in navigation bar CGContextSetBlendMode(context, kCGBlendModeOverlay); [tintColor setFill]; CGContextFillRect(context, rect); // mask by alpha values of original image [self drawInRect:rect blendMode:kCGBlendModeDestinationIn alpha:1.0f]; UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return tintedImage; }
Hier ist ein Beispiel für das Abtönen mehrerer Graustufenbilder mit Transparenz:
::
quelle
Sie können eine UIImage-Kategorie erstellen und dies folgendermaßen tun:
- (instancetype)tintedImageWithColor:(UIColor *)tintColor { UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0); CGContextRef context = UIGraphicsGetCurrentContext(); CGRect rect = (CGRect){ CGPointZero, self.size }; CGContextSetBlendMode(context, kCGBlendModeNormal); [self drawInRect:rect]; CGContextSetBlendMode(context, kCGBlendModeSourceIn); [tintColor setFill]; CGContextFillRect(context, rect); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
quelle
In iOS7 haben sie die Eigenschaft tintColor in UIImageView und renderingMode in UIImage eingeführt. Siehe mein Beispiel unter https://stackoverflow.com/a/19125120/1570970
quelle
Mit iOS 7.0 können Sie dies auch einfach tun, um eine grundlegende UIImageView zu tönen:
UIImage *iconImage = [[UIImage imageNamed:@"myImageName"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; UIImageView *icon = [[UIImageView alloc] initWithImage:iconImage]; icon.tintColor = [UIColor redColor];
quelle
Beachten Sie, dass in der akzeptierten Antwort von fabb der "umgebende" Code zum Erstellen eines UIImage die falsche Auflösung von Bildern auf dem Retina-Bildschirm ergab. Um dies zu beheben, ändern Sie:
UIGraphicsBeginImageContext(myIconImage.size);
zu:
UIGraphicsBeginImageContextWithOptions(myIconImage.size, NO, 0.0);
Der letzte Parameter, der auf 0.0 gesetzt ist, ist scale und laut Apple-Dokumentation:
Ich habe keine Erlaubnis zum Kommentieren und die Bearbeitung scheint etwas unhöflich zu sein, daher erwähne ich dies in einer Antwort. Nur für den Fall, dass jemand auf dasselbe Problem stößt.
quelle
UIImageView (oder eine beliebige Ansicht) hat eine Hintergrundfarbe, die RGBA ist. Das Alpha in der Farbe kann das tun, was Sie brauchen, ohne etwas Neues zu erfinden.
quelle
Nicht meine Arbeit, aber ich habe diesen Ansatz erfolgreich angewendet:
http://coffeeshopped.com/2010/09/iphone-how-to-dynamically-color-a-uiimage
quelle
Ich wollte meine Bildansichten in meiner benutzerdefinierten UIButton-Unterklasse schattieren, und die anderen Lösungen haben nicht das getan, was ich wollte. Ich musste die Bildfarbe abdunkeln. So ändern Sie die Helligkeit mit CoreImage.
Stellen Sie sicher, dass Sie CoreImage.framework zu den Bibliotheken Ihres Projekts hinzufügen. (Binär mit Bibliotheken verknüpfen)
UIImage Schattenmethode
- (UIImage *)shadeImage:(UIImage *)image { CIImage *inputImage = [CIImage imageWithCGImage:image.CGImage]; CIContext *context = [CIContext contextWithOptions:nil]; CIFilter *filter = [CIFilter filterWithName:@"CIColorControls" keysAndValues:kCIInputImageKey, inputImage, @"inputBrightness", [NSNumber numberWithFloat:-.5], nil]; CIImage *outputImage = [filter outputImage]; CGImageRef cgImage = [context createCGImage:outputImage fromRect:[outputImage extent]]; UIImage *newImage = [UIImage imageWithCGImage:cgImage scale:image.scale orientation:image.imageOrientation]; CGImageRelease(cgImage); return newImage; }
Sie möchten eine Kopie des Kontexts als ivar speichern, anstatt ihn neu zu erstellen.
quelle
Keine Antworten helfen mir beim Stapelüberlauf: Unsere Designer zeichnen UI-Elemente mit verschiedenen Formen, verschiedenen Alpha-Werten (und "Alpha-Löchern"). In den meisten Fällen handelt es sich um eine 32-Bit-PNG-Datei mit Alphakanal, die Schwarz-Weiß-Pixel (aller möglichen Intensitäten) enthält. Nachdem ich ein solches Bild getönt hatte, musste ich dieses getönte Ergebnis erzielen: weiße Pixel - über mehr getönt und dunkle Pixel - weniger. Und das alles im Hinblick auf den Alpha-Kanal. Und ich habe diese Methode für meine UIImage-Kategorie geschrieben. Vielleicht ist es nicht hocheffizient, aber es funktioniert als Uhr :) Hier ist es:
- (UIImage *)imageTintedWithColor:(UIColor *)color { UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale); CGContextRef context = UIGraphicsGetCurrentContext(); CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height); CGContextSetBlendMode(context, kCGBlendModeCopy); [color setFill]; CGContextFillRect(context, rect); [self drawInRect:rect blendMode:kCGBlendModeXOR alpha:1.0]; CGContextSetBlendMode(context, kCGBlendModeXOR); CGContextFillRect(context, rect); [self drawInRect:rect blendMode:kCGBlendModeMultiply alpha:1.0]; UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return coloredImage; }
quelle
Zunächst möchte ich mich bei fabb für seine außergewöhnliche Lösung bedanken, die mir geholfen hat, meine Aufgabe zu erfüllen, halbtransparente Symbole zu tönen. Da ich eine Lösung für C # (Monotouch) brauchte, musste ich seinen Code übersetzen. Folgendes habe ich mir ausgedacht. Kopieren Sie dies einfach, fügen Sie es in Ihren Code ein und fügen Sie Ihr halbtransparentes Bild hinzu.
Also gehen wieder alle Credits an fabb. Dies ist nur, um C # -Nutzer zu starten :)
//TINT COLOR IMAGE UIImageView iImage = new UIImageView(new RectangleF(12, 14, 24,24)); iImage.ContentMode = UIViewContentMode.ScaleAspectFit; iImage.Image = _dataItem.Image[0] as UIImage; UIGraphics.BeginImageContextWithOptions(iImage.Bounds.Size, false, UIScreen.MainScreen.Scale); CGContext context = UIGraphics.GetCurrentContext(); context.TranslateCTM(0, iImage.Bounds.Size.Height); context.ScaleCTM(1.0f, -1.0f); RectangleF rect = new RectangleF(0,0, iImage.Bounds.Width, iImage.Bounds.Height); // draw black background to preserve color of transparent pixels context.SetBlendMode(CGBlendMode.Normal); UIColor.Black.SetFill(); context.FillRect(rect); // draw original image context.SetBlendMode(CGBlendMode.Normal); context.DrawImage(rect, iImage.Image.CGImage); // tint image (loosing alpha) - the luminosity of the original image is preserved context.SetBlendMode(CGBlendMode.Color); UIColor.Orange.SetFill(); context.FillRect(rect); // mask by alpha values of original image context.SetBlendMode(CGBlendMode.DestinationIn); context.DrawImage(rect, iImage.Image.CGImage); UIImage coloredImage = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); iImage = new UIImageView(coloredImage); iImage.Frame = new RectangleF(12, 14, 24,24); //END TINT COLOR IMAGE cell.Add(iImage);
quelle