How to implement a Photoshop Curves editor in UIKit - ios

I'm familiar with UIBezierPath and the corresponding CG routines, but none of them appear to draw the same type of path as what I see in Photoshop, etc.
How would one go about this? I'm just talking about the UI--letting the user drag around points.
A java example I found is here: http://www.cse.unsw.edu.au/~lambert/splines/natcubic.html

I would look into CGContextAddCurveToPoint and drag around curve's control points. If you require more control points to create a complex curve, just split a resulting curve into simple segments.
Take a look at this article It explains how to calculate the control points based on knots you have on your curve.

Related

How to draw a smooth shape based on 4 points in iOS?

I'm using Sketch to draw a share like the picture below
Basically,the shape has 4 control points,and I want to connect these points into a shape smoothly
I tried UIBezierPath, but it seems that the API doesn't work for me. E.g, the Right Point shown in the picture, which I need the line to actually cross it, while I drag each of these 4 points, I can get a smooth shape, how can I achieve that?
You want something called Catmull-Rom splines. That is a kind of spline where all the control points lie on the curve.
The problem you'll face with Catmull-Rom splines is that with some control points, you can introduce loops or kinks in your curve that you don't want.
I have a project called RandomBlobs on github that demonstrates how to do this.
Here is a Youtube video showing the output of the app:
(Credit to Erica Sadun, author of the outstanding "iOS Developers' Cookbook" series for the technique. And a disclaimer. I was one of the technical reviewers on a couple of her books, but I did so because I really like her writing and wanted to help.)

How can I draw this complex shape using iOS Quartz 2D drawing?

I know how to draw simple shapes - rectangles, ellipses and lines etc. using iOS Quartz 2D drawing.
Just now I'm trying to draw a relatively complex shape though, the tail of a musical quaver:
Can anybody suggest a good way to approach this problem?
Can you design the quaver in a graphics program like Inkscape, export as an SVG, and then render using SVGKit? From a development level, it would be much easier to maintain something that you can visually update, rather than trying to draw a shape with code.
What I have learned from my designers is, that you start with a simple form and then extend and change it in single, small steps. Sometime later you arrive at the complex form. So, like answered by #Duncan C building a path. Now I know that is quite tedious. One alternative not mentioned here is PaintCode, an app that produces Cocoa code from your drawing. It is called PaintCode and should do what you want. Btw I am not affiliated with the makers of PaintCode!
You could draw that as a filled UIBezierPath (which is a UIKit wrapper on a CGPath).
You'd open a path, draw a sequence of straight lines and cubic or quadratic bezier curves, then close the path. Then you'd draw it as a filled path.
Once you have the path created, you could draw it with a single call.
A couple of alternatives, as Duncan seems to have answered this.
One option would be to dynamically scale a high resolution image.
There is one caveat with this approach: you should not scale anything below 1/2 of the original size, otherwise the interpolation tends to glitch.
So you would need to store image at say 64x64, 128x128, 256x256 etc
You could pack all of these into a single 256x512, and this is what a lot of games do.
Another option is to render a quaver unicode character http://www.fileformat.info/info/unicode/char/266a/index.htm

iOS drawRect, finding points on a curve

I will draw a curve similar to the red curve in the illustration below (can be a bezier or whatever is most convenient for my purposes I think). I would like to find points on the curve (blue dots in the illo). The points would most likely be divisions of equal parts of the length of the curve.
Can I find these points? I am not seeing a solution in the docs as of yet.
This answer covers segmentation of a Bezier curve using the de Casteljau algorithm. You already have your parameterized values along the curve for segmentation.
(If you follow the link referenced in the answer make sure you have java enabled in your browser, so you can view the example visualisations).

How can I render a square bitmap to an arbitrary four-sided polygon using GDI?

I need to paint a square image, mapped or transformed to an unknown-at-compile-time four-sided polygon. How can I do this?
Longer explanation
The specific problem is rendering a map tile with a non-rectangular map projection. Suppose I have the following tile:
and I know the four corner points need to be here:
Given that, I would like to get the following output:
The square tile may be:
Rotated; and/or
Be narrower at one end than at the other.
I think the second item means this requires a non-affine transformation.
Random extra notes
Four-sided? It is plausible that to be completely correct, the tile should be
mapped to a polygon with more than four points, but for our purposes
and at the scale it is drawn, a square -> other four-cornered-polygon
transformation should be enough.
Why preferably GDI only? All rendering so far is done using GDI, and I want to keep the code (a) fast and (b) requiring as few extra
libraries as possible. I am aware of some support for
transformations in GDI and have been experimenting with them
today, but even after experimenting with them I'm not sure if they're
flexible enough for this purpose. If they are, I haven't managed to
figure it out, and so I'd really appreciate some sample code.
GDI+ is also ok since we use it elsewhere, but I know it can be slow, and speed is
important here.
One other alternative is anything Delphi- /
C++Builder-specific; this program is written mostly in C++ using
the VCL, and the graphics in question are currently painted to a
TCanvas with a mix of TCanvas methods and raw WinAPI/GDI calls.
Overlaying images: One final caveat is that one colour in the tile may be for color-key
transparency: that is, all the white (say) squares in the above tile
should be transparent when drawn over whatever is underneath.
Currently, tiles are drawn to square or axis-aligned rectangular
targets using TransparentBlt.
I'm sorry for all the extra caveats that make this question more complicated
than 'what algorithm should I use?' But I will happily accept answers with
only algorithmic information too.
You might also want to have a look at Graphics32.
The screen shot bewlow shows how the transfrom demo in GR32 looks like
Take a look at 3D Lab Vector graphics. (Specially "Football field" in the demo).
Another cool resource is AggPas with full source included (download)
AggPas is Open Source and free of charge 2D vector graphics library. It is an Object Pascal native port of the Anti-Grain Geometry library - AGG, originally written by Maxim Shemanarev in C++. AggPas doesn't depend on any graphic API or technology. Basically, you can think of AggPas as of a rendering engine that produces pixel images in memory from some vectorial data.
Here is how the perspective demo looks like:
After transformation:
The general technique is described in George Wolberg's "Digital Image Warping". It looks like this abstract contains the relevant math, as does this paper. You need to create a perspective matrix that maps from one quad to another. The above links show how to create the matrix. Once you have the matrix, you can scan your output buffer, perform the transformation (or possibly the inverse - depending on which they give you), and that will give you points in the original image that you can copy from.
It might be easier to use OpenGL to draw a textured quad between the 4 points, but that doesn't use GDI like you wanted.

OpenCV Identifying Lines and Curves

I'm just starting to learn OpenCV programming. May I just ask about how can I identify lines and curves in OpenCV? My problem is that I have to identify if the image contains a convex or concave (horizontal or vertical curve) curve, a vertical, diagonal or a horizontal line.
In my code, I used CvSetImageROI to take a particular part of an image, and then I'm trying to identify each according to the said lines/curves.
Are there functions in OpenCV that are available? Thank you very much for the help. By the way, i'm using Linux and C++.
Hough transform http://en.wikipedia.org/wiki/Hough_transform, http://homepages.inf.ed.ac.uk/rbf/HIPR2/hough.htm
is the standard way to do it. In its simple form (as implemented in OpenCV) it can detect lines of arbitray position and angle and line segments.
Look here for an example
http://opencv.itseez.com/modules/imgproc/doc/feature_detection.html?highlight=hough#houghlinesp
For curves, the detection process is a bit more complicated, and you need the general Hough transform It is not yet available in OCV, but you can write it as an exercise or look for a good implementation.
http://en.wikipedia.org/wiki/Generalised_Hough_transform describes it (in short)

Resources