iOS FloodFill : UIImage vs Core Graphics - ios

I'm considering building an app that would make heavy use of a flood fill / paint bucket feature. The images I'd be coloring are simply like coloring book pages; white background, black borders. I'm debating which is better to use UIImage (by manipulating pixel data) or drawing the images with Core Graphics and changing the fill color on touch.
With UIImage, I'm unable to account for retina images properly; it destroys the image when I write the context into a new UIImage, but I can probably figure out. I open to tips though...
With CoreGraphics, I have no idea how to calculate which shape to fill when a user touches an area and then actually filling that area. I've looked but I have not turned up a successful search.
Overall, I believe the optimal solution is using CoreGraphics, since it'll be lighter overall and I won't have to keep several copies of the same image for different sizes.
Thoughts? Go easy on me! It's my first app and first SO question ;)

I'd suggest using Core Graphics.
Instead of images, define the shapes using CGPath or NSBezierPath, and use Core Graphics to stroke and/or fill the shapes. Filling shapes is then as easy as switching drawing mode from just stroking to stroking and filling.
Creating even more complex shapes is made much easier with the "PaintCode" app (which lets you draw and creates the path code for you).
As your first app, I would suggest something with a little less custom graphics fiddling, though.

Related

Is there a way to purposely turn off all anti-aliasing for UIView?

I'm trying to make a kind of old-looking app, and so as a result I want my UIView's to be rendered without anti-aliasing. In other words I want my views to be pixelized ,especially the view.layer.cornerRadius, as in this case I am able to layout my views using AutoLayout.
This would make it much easier than drawing different pixel arts for different iPhone sizes. Moreover, if I did draw the pixel art whenever a view is resized I would have to create a new pixel art as scaling the images vould distort the pixel art.
The only thing that I have found is view.layer.allowsEdgeAntialiasing which by default is already set to false. I was also thinking to use the Core Graphic's BeizerPaths to draw the pixelized shadows and corners, would this be a viable way to achieve what I want?
You can go down to the Core Graphics CGContext and friends, and you can specifically tell the Graphics Context to shut off anti-aliasing, with CGContextSetShouldAntialias(context, false);
Here are two small screen grabs, one with no jaggies, and the other with jaggies.

Adding border to edges of opaque area of UIImage with a filter

Hello: Currently in my project, I'm using OBShapedButton to process touches on a lot of objects that overlap (it's a map with each territory its own separate object). Basically, this library prevents a touch from being processed on a transparent point on the given view.
I'm attempting to add a border effect to just the edges of the opaque part of the UIImage (and adding a semi-transparent overlay above that). Something to the effect of this:
Which can be simplified to this (example of one image):
I am currently using MGImageUtilities to color in the opaque parts of territories using this line:
[territory setImage:[[territory image] imageTintedWithColor:tint]];
The problem is that I'm not sure how to just color the borders (which can be any shape). I've looked at this link already, but haven't been able to come up with anything.
Thanks in advance for the help!
Terribly hacky, but use MGImageUtilities' UIImage+ProportionalFill with scale resizing to create a slightly larger image, UIImage+Tint to red, and stack below.
The library you are using doesn't actually specify a shape layer. It uses alpha values from the PNGs that you give it.
Could you use a different 'highlighted' or 'selected' PNG that adds the border effect you are looking for?
Otherwise, it you will have to generate a UIBezierPath from your PNG image, which sounds like a very computationally intensive operation. At that point, I might question whether this library meets your needs.

How to paint using brush with particular area...

I want to fill each and every part with different colours like circle with other colour and each leave with different colour and stick with different colours. I have bunch of colours. You can fidn similar apps like Toonia Color book on apple app store...
I am unable to get bounds of particular part in image.
I searched a whole day before writing this question. Every one is saying just look for flood fill and Quick Fill algorithms but i am not able to solve this problem.
In Toonia Colorbook this is done using vector graphics and masks. Every shape is described as a bezier curve that masks a drawing layer.
check out CAShapeLayer and CALayer for further details

What is the best way to use layers and partial rendering in iOS for speed

I'm working on a graphing application which I wrote using Core Graphics. I have a buffer which accumulates data, and I render it on the screen. It's super slow and I want to avoid going to openGL if possible. According to the profiler, drawing my graph data is what's killing me (which consists of a number of points which are converted to a path, followed by the calls AddPath, DrawPath)..
This is what I want to do, my question is how to best implement it using layers / views / etc..
I have a grid and some text. I want this to be rendered in a CALayer (or some other layer/view?) and only update when required (the graph is rescaled).
Only a portion of the data needs to be refreshed. I want to take the previous screen buffer, erase a rectangle's worth of data (or cover it with a white box) and then draw only the portion of the graphs that have changed.
I then want to merge the background layer with the foreground graphs to generate the composite image. This requires the graph layer to have a transparent background so as not to obscure the grid.
I've looked at using CAlayer as a sublayer, but it doesn't seem to provide a simple way to draw a line. CAShapeLayer seems a bit better, but it looks like it can only draw a single line. I want the grid to be composed of multiple lines.
What's the best approach and combination of objects to allow me to do this?
Thanks,
Reza
I'd have a CGLayerRef that was used for drawing the path into. For each new point I'd draw just the new segment. When the graph got to full width I'd create a new CGLayerRef and start drawing the new line segments into that.
What happens to the previous layer as it's drawn over by the new layer depends on how your graph is displayed, but you could clear the section which is now underneath the new layer (using CGContextSetBlendMode(context, kCGBlendModeClear);) or you could choose to blend them together in some other way.
Drawing the layers each time you make a change to the lines they contain is relatively cheap compared to drawing all of the line segments themselves.
Technically, there would also be CALayers used to manage the drawing of the CGLayerRefs to the screen (via the delegate relationship drawLayer:inContext:), but all of the line drawing is done using the CGLayerRefs context and then the CGLayerRef is drawn as a whole into the CALayers context (CGContextDrawLayerInRect(context, frame, backingCGLayer);).

ios iPaint from WWDC 2012

In the Video Session 506 of Apples WWDC 2012 they showed a painting app which is made for high performance drawings (so the frame rate never gets below 30).
I tried to replicate the code but get stuck on multiple points.
What I am looking for is a basic drawing app (lines, Squares, Circles, bezier paths), which performs well even after hundreds of lines have been drawn.
The basic approach is to save the drawn lines (or circles bezierpaths etc) to an image after a certain numbers of them have been drawn, and then only refresh the new drawings, therefore not having to redraw all the already drawn lines.
But somehow I never get to a higher performance. How do I need to implement this? Do I need multiple layers? And how do I manage that not all layers in a view are redrawn, but only a certain sublayer?
If someone could provide me with a short example of a few lines drawn on an layer, then saving that layer to an image, an then drawing on top of that I would really appreciate it.
Thank you for any help to recreate the iPaint application, which is unfortunately not available for download from apple.
That is only half of the puzzle. The other half is to only refresh the minimum possible area of the view (via setNeedsDisplayInRect:). However, I have been through many different ways of drawing via Core Graphics. The caching is fine, but I don't use it anymore. I set the update rectangle as above, and then test each path before I stroke it (testing is fast, stroking is slow). If it is inside the update box, I stroke it, otherwise I ignore it.
I did not look at that session, but a traditional Quartz speedup has been to use CGLayers (not CALayers). You can think of a CGLayer as a cached drawing which may or may not be a bitmap (the system decides how best to cached it). If you have a backing bitmap context, you can use that as your "image" and draw the CGLayers into that (and then discard the layers) as you see fit. Read up on CGLayer (its in the Quartz documentation) and then see if this was what they talked about in that session.

Resources