Convert openCV Rect coordinates into CGRect coordinates in iOS - ios

I want to convert openCV rectangle coordinates into CGRect so I can draw image using this.
rectangle(frame, box, Scalar(0,0,255));
In the below code I create the rectangle with these parameters as frame is mat type ,box is CGRect type.
In openCV it display rectangle correctly but I need to create UIImage with same frame.
Any help will be appreciated.
Thanks.

Related

RMProjectedRect to CGRcet

I want to draw bounding box shape for RMProjectedRect structs.
I need to convert RMProjectedRect to CGRect and and then create a shape and add it to superview.
does anyone know how to do this conversion?
You will want to use the RMMapView routines under Converting Map Coordinates here:
https://www.mapbox.com/mapbox-ios-sdk/api/Classes/RMMapView.html
You can convert corners of the RMProjectedRects into pixels coordinates for a given map viewport.
thanks for your hint.
Here is what I did:
CGRect frameRect = {[self.mapView projectedPointToPixel:gridMapRect.origin], [self.mapView projectedSizeToViewSize:gridMapRect.size]};

Crop Image With Desire Rect

Many questions are available on SO, but unfortunately I couldn't solve my problem using them.
I've added a overlay view on my camera, and now want to get image within the blue border (only water bottle).
I tried code chunks like following
CGImageRef imageRef = CGImageCreateWithImageInRect([largeImage CGImage], cropRect);
[UIImageView setImage:[UIImage imageWithCGImage:imageRef]];
CGImageRelease(imageRef);
but having two issues
Either cropped image is getting too big
The orientation changes to -90.
for point 1, I think I'm providing cropRect too small thats why it showing very small part of image with too zoomed view. on my other viewController I have UIImageView (where cropped image need to display) of same size as camera rect within blue border.
So question is how to crop the image and what values should I provide for cropRect?
Assuming the image size 1280* 1080 and your crop view size 320*480 You need to do the following
Convert your crop view's frame to Image size rect (0, 0, 1280, 1080) by find the scale factor
float xScale = 1280 / 320;
float yScale = 1080 / 480;
float scaleFactor = (xScale < yScale) ? xScale : yScale;
Multiply cropView frame by scale factor. This will map the screen coordinates to image size coordinates. Then use the new cropRect with the
CGImageCreateWithImageInRect([largeImage CGImage], cropRect);
The problem with different orientation is that CoreGraphics uses a different coordinate system as compare to view's coordinate system. Quartz 2D Coordinate Systems so try setting
[UIImage imageWithCGImage:imageRef].imageOrientation = largeImage.imageOrientation

iOS: Creating a rectangle with holes using Core Graphics

I have an MKMapView where I want to grey out parts of the map. More specifically, I want to have some circles and rectangles which are displayed normally and the rest of the map has a semi-transparent grey layer. Something like this:
For that, I think that I should subclass MKOverlay and MKOverlayRenderer. As Apple suggests, in my MKOverlayRenderer subclass, I should override the drawMapRect:zoomScale:inContext: method, and draw my stuff using Core Graphics. My question is how can I draw the following with Core Graphics?
I have spent some hours looking at masking and clipping using Core Graphics, but I haven't found anything similar to this. The QuartzDemo has some examples of clipping and masking. I guess clipping with either the even-odd or nonzero winding number rules won't work for me, as the rectangles and circles are dynamic. I think I have to create a mask somehow, but I can't figure out how. The QuartzDemo creates a mask out of an image. How could I create a mask using rectangles and circles? Is there any other way I could approach this?
Thank you
You should be able to setup a context with transparency, draw the skinny rectangles and circles without stroking them, draw a rectangle border around the whole context, and then fill the shape with the darker color. You'll need to look into fill order rules to make sure that the larger space is what is filled rather than the smaller joined shapes.
I guess clipping with either the even-odd or nonzero winding number rules won't work for me, as the rectangles and circles are dynamic.
This shouldn't matter.
Well, I worked it out myself. I have to create my own mask. This is done by drawing the "hole" shapes, outputting this to an ImageRef, and inverting this ImageRef to output the mask. Here is a code snippet that could work if you add it in the QuartzDemo project->QuartzClipping.m->QuartzClippingView class, at the end of the drawInContext method.
-(void)drawInContext:(CGContextRef)context {
// ...
CGContextSaveGState(context);
// dimension of the square mask
int dimension = 20;
// create mask
UIGraphicsBeginImageContextWithOptions(CGSizeMake(dimension, dimension), NO, 0.0f);
CGContextRef newContext = UIGraphicsGetCurrentContext();
// draw overlapping circle holes
CGContextFillEllipseInRect(newContext, CGRectMake(0, 0, 10, 10));
CGContextFillEllipseInRect(newContext, CGRectMake(0, 7, 10, 10));
// draw mask
CGImageRef mask = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext());
UIGraphicsEndImageContext();
// the inverted mask is what we need
CGImageRef invertedMask = [self invertMask:mask dimension:dimension];
CGRect rectToDraw = CGRectMake(210.0, height - 290.0, 90.0, 90.0);
// everything drawn in rectToDraw after this will have two holes
CGContextClipToMask(context, rectToDraw, invertedMask);
// drawing a red rectangle for this demo
CGContextFillRect(context, rectToDraw);
CGContextRestoreGState(context);
}
// taken from the QuartzMaskingView below
- (CGImageRef)invertMask:(CGImageRef)originalMask dimension:(int)dimension{
// To show the difference with an image mask, we take the above image and process it to extract
// the alpha channel as a mask.
// Allocate data
NSMutableData *data = [NSMutableData dataWithLength:dimension * dimension * 1];
// Create a bitmap context
CGContextRef context = CGBitmapContextCreate([data mutableBytes], dimension, dimension, 8, dimension, NULL, (CGBitmapInfo)kCGImageAlphaOnly);
// Set the blend mode to copy to avoid any alteration of the source data
CGContextSetBlendMode(context, kCGBlendModeCopy);
// Draw the image to extract the alpha channel
CGContextDrawImage(context, CGRectMake(0.0, 0.0, dimension, dimension), originalMask);
// Now the alpha channel has been copied into our NSData object above, so discard the context and lets make an image mask.
CGContextRelease(context);
// Create a data provider for our data object (NSMutableData is tollfree bridged to CFMutableDataRef, which is compatible with CFDataRef)
CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFMutableDataRef)data);
// Create our new mask image with the same size as the original image
return CGImageMaskCreate(dimension, dimension, 8, 8, dimension, dataProvider, NULL, YES);
}
Any easier/more efficient solution is welcome :)

Flip video around arbitrary axis

I have a video recorded by the user. I want the user to be able to define an arbitrary axis of rotation, and flip the video along that axis. I also want the final flipped video to crop to the original size.
I have used the CGAffineTransformMakeScale(-1, 1) to flip the video along the horizontal axis, but that's around the center point.
I'm already using an AVMutableComposition to do some compositing. Are there any AVMutableVideoCompositionLayerInstruction that would help?
_mike
You should calculate where the user set the axis or how far the image is off set, flip the image and re-apply this offset in the opposite direction. Then you just need to get a subimage of an image.
Which you can do by doing this:
CGRect fromRect = CGRectMake(0, 0, 320, 480); // or whatever rectangle
CGImageRef drawImage = CGImageCreateWithImageInRect(image.CGImage, fromRect);
UIImage *newImage = [UIImage imageWithCGImage:drawImage];
CGImageRelease(drawImage);
Code Reference Subimage of Image

cgcontext rotate rectangle

guys!
I need to draw some image to CGContext.This is the relevant code:
CGContextSaveGState(UIGraphicsGetCurrentContext());
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect rect = r;
CGContextRotateCTM(ctx, DEGREES_TO_RADIANS(350));
[image drawInRect:r];
CGContextRestoreGState(UIGraphicsGetCurrentContext());
Actually,the rectangle is rotate and display on a area what is not my purpose.I just want to
rotate the image and display on the same position.
Any ideas ?????
Rotation is about the context's origin, which is the same point that rectangles are relative to. If you imagine a sheet of graph paper in the background, you can see what's going on more clearly:
The line is the “bottom” (y=0) of your window/view/layer/context. Of course, you can draw below the bottom if you want, and if your context is transformed the right way, you might even be able to see it.
Anyway, I'm assuming that what you want to do is rotate the rectangle in place, relative to an unrotated world, not rotate the world and everything in it.
The only way to rotate anything is to rotate the world, so that's how you need to do it:
Save the graphics state.
Translate the origin to the point where you want to draw the rectangle. (You probably want to translate to its center point, not the rectangle's origin.)
Rotate the context.
Draw the rectangle centered on the origin. In other words, your rectangle's origin point should be negative half its width and negative half its height (i.e., (CGPoint){ width / -2.0, height / -2.0 })—don't use the origin it had before, because you already used that in the translate step.
Restore the gstate so that future drawing isn't rotated.
What worked for me was to first use a rotation matrix to calculate the amount of translation required to keep your image centered. Below I assume you've already calculated centerX and centerY to be the center of your drawing frame and 'theta' is your desired rotation angle in radians.
let newX = centerX*cos(theta) - centerY*sin(theta)
let newY = centerX*sin(theta) + centerY*cos(theta)
CGContextTranslateCTM(context,newX,newY)
CGContextRotateCTM(context,theta)
<redraw your image here>
Worked just fine for me. Hope it helps.
use following code to rotate your image
// convert degrees to Radians
CGFloat DegreesToRadians(CGFloat degrees)
{
return degrees * M_PI / 180;
};
write it in drawRect method
// create new context
CGContextRef context = UIGraphicsGetCurrentContext();
// define rotation angle
CGContextRotateCTM(context, DegreesToRadians(45));
// get your UIImage
UIImage *img = [UIImage imageNamed:#"yourImageName"];
// Draw your image at rect
CGContextDrawImage(context, CGRectMake(100, 0, 100, 100), [img CGImage]);
// draw context
UIGraphicsGetImageFromCurrentImageContext();

Resources