On Sep 29, 2013, at 7:37 PM, Paul Scott <psc...@skycoast.us> wrote:

> 
> On Sep 29, 2013, at 6:54 PM, Kyle Sluder <k...@ksluder.com> wrote:
>> 
>>> How do I get an image rendered in the tint color?
>> 
>> Start a bitmap context, set your template image as the image mask, set the 
>> full color to the appropriate tintColor, and fill the bounds of the context.
>> 
>> Construct a data URI out of the image you get by closing the bitmap context.
> 
> 
> That works. Thanks. I was already heading down that path, since it seemed 
> kind of obvious after thinking about it. Nevertheless, there are some strange 
> and non-obvious dependencies that exist with various Cocoa and CG objects 
> that aren't particularly well documented, such as [colorObject setFill]; I 
> mean, what kind of magic happens there?

No magic. You could implement it yourself:

@implementation UIColor
- (void)setFill
{
 CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), self.CGColor);
}
@end

> Normally, I'd expect an instance method to operate on the receiver; but by 
> this incantation the graphics context is involved.

It mimics the NSColor API, which is in turn reflective of the stack-based 
nature of the Postscript programming language which used to underlie the 
graphics system of the NeXT. In traditional PostScript, you push a color, then 
push the operator to select that color as the fill color.

There's only one graphics context in traditional Postscript; when Display 
Postscript was conceived, the concept of multiple graphics contexts was 
introduced by maintaining a stack of graphics contexts. This minimizes conflict 
with traditional PostScript because all operators affect the "current context" 
at the top of the stack.

Core Graphics doesn't need to maintain that compatibility; the API requires the 
programmer to specify the graphics context for every operation. CG _does_ 
maintain the idea of a stack of graphics states _within_ a context. AppKit and 
UIKit independently build the idea of a stack of _contexts_ atop Core Graphics. 
On the Mac, the interface is +[NSGraphicsContext currentContext]; on iOS, it's 
UIGraphicsGetCurrentContext().

> 
>   UIImage *image = [controller.infoIcon.image 
> imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

You don't need this anymore; the image data is not going to change. I doubt it 
will hurt all that much. If you want to build a reusable 
ImageByTintingTemplateImage() function out of your code, perhaps instead of 
creating a template version of the image, you could assert that the image is 
already a template; that puts the onus on the caller to verify (or at least 
emptily promise) that they're handing you the correct asset to be tinted.

>   NSString *data = [UIImagePNGRepresentation(image) 
> base64EncodedStringWithOptions:nil];
>   [webView stringByEvaluatingJavaScriptFromString:
>       [NSString stringWithFormat:@"%@%@%@",
>           @"( function() {"
>           @"    var x = document.getElementById('infoIcon');"
>           @"    if ( !! x ) { "
>           @"        x.src = 'data:image/png;base64,", data, @"';"
>           @"    }"
>           @"})();"
>       ]
>   ];

Rather than building up and executing a _very_ long JavaScript, would you be 
better off accessing the DOM directly?

--Kyle Sluder

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to