I want to do this:
draw an image using Quartz 2D, the image look like rotated according to its y axis in a 3D space, like this:
Is Quartz 2D capable to do this?
No, you cannot do this directly with Quartz 2D. It supports only affine transformations, which always preserve parallel lines.
(It's clear that you want the parallel lines on the top and bottom edges of your figure to become non-parallel.)
The term you're looking for is "perspective transformation", if you want to search for other ways to achieve this result.
I don't know how to do it in 2d, but its really easy to do it with quartz using this kind of call:
yourView.layer.transform = CATransform3DMakeRotation(M_PI/4, 0.0, 0.0, 1.0);
You should look into using the CATransform3D's. They are pretty powerful and easy to call.
Related
I am stuck in my application feature. I want cropping feature similar to Cam Scanner Cropping.
The screens of CAM-SCANNER are:
I have created similar crop view.
I have obtained CGPoint of four corners.
But How can I obtained cropped image in slant.
Please provide me some suggestions if possible.
This is a perspective transform problem. In this case they are plotting a 3D projection in a 2D plane.
As, the first image has selection corners in quadrilateral shape and when you transform it in a rectangular shape, then you will either need to add more pixel information(interpolation) or remove some pixels.
So now actual problem is to add additional pixel information to cropped image and project it to generate second image. It can be implemented in various ways:
<> you can implement it by your own by applying perspective tranformation matrix with interpolation.
<> you can use OpenGL .
<> you can use OpenCV.
.. and there are many more ways to implement it.
I had solved this problem using OpenCV. Following functions in OpenCV will help you to achieve this.
cvPerspectiveTransform
cvWarpPerspective
First function will calculate transformation matrix using source and destination projection coordinates. In your case src array will have values from CGPoint for all the corners. And dest will have rectangular projection points for example {(0,0)(200,0)(200,150)(0,150)}.
Once you get transformation matrix you will need to pass it to second function. you can visit this thread.
There may be few other alternatives to OpenCV library, but it has good collection of image processing algorithms.
iOS application with opencv library is available at eosgarden.
I see 2 possibilities. The first is to calculate a transformation matrix that slants the image, and installing it in the CATransform3D property of your view's layer.
That would be simple, assuming you knew how to form the transformation matrix that did the stretching. I've never learned how to construct transformation matrixes that stretch or skew images, so I can't be of any help. I'd suggest googling transformation matrixes and stretching/skewing.
The other way would be to turn the part of the image you are cropping into an OpenGL texture and map the texture onto your output. The actual texture drawing part of that would be easy, but there are about 1000 kilos of OpenGL setup to do, and a whole lot to learning in order to get anything done at all. If you want to pursue that route, I'd suggest searching for simple 2D texture examples using the new iOS 5 GLKit.
Using the code given in Link : http://www.hive05.com/2008/11/crop-an-image-using-the-iphone-sdk/
Instead of using CGRect and CGContextClipToRect Try using CGContextEOClip OR CGContextClosePath
Though i havnt tried this... But i have tried drawing closed path using CGContextClosePath on TouchesBegan and TouchesMoved and TouchesEnd events.
Hope this can give more insight to your problem...
I know that drawing a point by using drawing a line method in Quartz 2D is
CGContextMoveToPoint(context,x,y-0.5f);
CGContextAddLineToPoint(context,x,y+0.5f);
Is there any other possible way to draw a point using Quartz?
I meant, some direct way of doing so?
CGContextFillRect(context, CGRectMake(x,y,1,1));
if you want it to look like a circular point try this:
CGContextStrokeEllipseInRect(context, CGRectMake(x, y, 4, 4));
it will draw for you you a an ellipse inside a rectangle (above case is apparently a square). i prefer you to choose a square as it will look like a real circle and not oval one. however, this circle will be empty from the inside, you can fill it by a stroke. (but it looks cool like a donut!) :)
I am stuck in my application feature. I want cropping feature similar to Cam Scanner Cropping.
The screens of CAM-SCANNER are:
I have created similar crop view.
I have obtained CGPoint of four corners.
But How can I obtained cropped image in slant.
Please provide me some suggestions if possible.
This is a perspective transform problem. In this case they are plotting a 3D projection in a 2D plane.
As, the first image has selection corners in quadrilateral shape and when you transform it in a rectangular shape, then you will either need to add more pixel information(interpolation) or remove some pixels.
So now actual problem is to add additional pixel information to cropped image and project it to generate second image. It can be implemented in various ways:
<> you can implement it by your own by applying perspective tranformation matrix with interpolation.
<> you can use OpenGL .
<> you can use OpenCV.
.. and there are many more ways to implement it.
I had solved this problem using OpenCV. Following functions in OpenCV will help you to achieve this.
cvPerspectiveTransform
cvWarpPerspective
First function will calculate transformation matrix using source and destination projection coordinates. In your case src array will have values from CGPoint for all the corners. And dest will have rectangular projection points for example {(0,0)(200,0)(200,150)(0,150)}.
Once you get transformation matrix you will need to pass it to second function. you can visit this thread.
There may be few other alternatives to OpenCV library, but it has good collection of image processing algorithms.
iOS application with opencv library is available at eosgarden.
I see 2 possibilities. The first is to calculate a transformation matrix that slants the image, and installing it in the CATransform3D property of your view's layer.
That would be simple, assuming you knew how to form the transformation matrix that did the stretching. I've never learned how to construct transformation matrixes that stretch or skew images, so I can't be of any help. I'd suggest googling transformation matrixes and stretching/skewing.
The other way would be to turn the part of the image you are cropping into an OpenGL texture and map the texture onto your output. The actual texture drawing part of that would be easy, but there are about 1000 kilos of OpenGL setup to do, and a whole lot to learning in order to get anything done at all. If you want to pursue that route, I'd suggest searching for simple 2D texture examples using the new iOS 5 GLKit.
Using the code given in Link : http://www.hive05.com/2008/11/crop-an-image-using-the-iphone-sdk/
Instead of using CGRect and CGContextClipToRect Try using CGContextEOClip OR CGContextClosePath
Though i havnt tried this... But i have tried drawing closed path using CGContextClosePath on TouchesBegan and TouchesMoved and TouchesEnd events.
Hope this can give more insight to your problem...
Say the user taps 4 spots on the iphone, defining an irregular 4 sided polygon (in 2d space). Is there a way to map/fit a (potentially highly distorted) image onto this shape, without using OpenGL?
Something like:
Is my only option to somehow calculate the 3d space that my irregular 4 sided shape sits in (based on where the tapped 2d points sit), create an OpenGL plane in that space, and map my texture to it flatly? Seems like there should be an easier way...
Thanks in advance.
Update: After diving into OpenGL I'm almost there... but I still can't get the texture to distort correctly. The triangulation seems to be messing with the texture mapping:
I can't answer your question completely, but one thing I would say is that you don't need to think about any conversion / mapping to 3D. Using OpenGL you can easily draw the shape in 2D and have the texture mapped as you desire. No need for any fancy maths or conversions. It's no more complicated than drawing a rectangle. OpenGL doesn't care that your 4-sided shape isn't actually rectangular.
i want to rotate image in quartz 2d around one corner..i want to make analog clock.
You should probably start with the Quartz 2D Programming Guide. In particular, check out the section on transforms, this covers rotation.
Essentially what you need to do is apply a transform matrix for rotation to the Current Transform Matrix (CTM). This defines the mapping of the coordinates that you draw to and the coordinates that are displayed on the user's device.
Quartz does make this all fairly straightforward to do in code; the link above has example code.
For example, you could do something like :
CGAffineTransform transform = CGAffineTransformMakeRotation(ANGLE_IN_RADIANS);
view.transform = transform;
And if you want a smoother animation, try using an UIView Animation.
But if you need an other rotation, you should check the documentation :-)
Good Luck !