Wednesday, September 07, 2011

Making UIImages with blocks

So i was going to post about something completely different today, but as i was typing i looked at my code, and thought it was verbose and a little bit ugly.

So i made it awesome, and as everyone knows to make your code awesome you add some blocks to it.

My problem was simple, i was faced with the need to create two CGBitmapContext, for the uniformed the following code is required to prepare a bitmap context for drawing.


So after a bit of thought, i decided what i really wanted was a method that did all of this for me, and meant that i didn't have to worry about constantly checking the code for leaks (DRY), and that was pleasant to look at and i came up with the above. The block that you pass in is given a fully formed CGBitmapContext, and the method returns a UIImage generated from that context. Almost like a UIView/CALayer.



So now your thinking, "Yeah, thats cool, but why the [INSERT FOUR LETTER WORD] would i want to use it ?" Well young grasshopper, have you ever wanted to mask a image in code? You know to do those trendy rounded corners ... well yes you can use CALayer's however the idea of using those off the main thread makes me uneasy, and we all know the cool kids do things in the background.


The above actually creates a rounded rect on the fly, and masks the image with it. It's made to be used in a category on UIImage. But look closer, yep thats right kids, no boiler plate, ZERO, NADA, 另, SQUAT (i think you get the point)!

I should take a moment to mention that the awesome code for the rounded rect comes from the awesome Oliver Drobnik, i have the utmost respect for this guy, not just for this snippet, but if you've ever seen his Rich text label and it's associated projects, you'll understand why real soon.

2 comments:

Omid M. said...

very awesome code you've written.

I had a problem of sorts with getting rounded corners myself a while ago.

My problem came from the combination of these UIImage categories for generating rounded UIImages and using sdwebimage for background downloading and caching of images.

UIImage Categories
http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

SDWebImage
http://www.iosdevnotes.com/tag/sdwebimage/

At the time I was trying to quickly solve the problem without changing SDWebImage. but that's probably how I should solve it.

anyways just wanted to share and likewise curious how you use this with downloading images.

Unknown said...

Firstly, those UIImage categories are awesome, definitely gonna start using it.

In one of my projects, i use UITableView's willDisplayCell: method to see when a cell becomes visible. I then use ASIHTTPRequest to request the image, this request has a reference to the cell's backing model object. And when the image is downloaded, if changes a flag in the model.

Before i flip this flag, the images are masked and saved to disk.

the cells are setup to observe this flag, and so change by themselves once the image has been downloaded.

Now if you don't want to copy me, you could just find the callback from the HTTP request within SDWebImage and have modify it to return the image with rounded corners. Or you could modify the UIImageView's layer, and mask it's bounds, not sure if that will work though.