Select and crop face image from photo image (ios) - ios

I'm trying to get cropped image from photo. I have the following code that crop image that was got from ios face detection sdk:
- (UIImage *)scaleAndRotateImage:(CIFeature *)ciFeature image:(UIImage *)image {
static int kMaxResolution = 640;
CGImageRef imgRef = image.CGImage;
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
if (width > kMaxResolution || height > kMaxResolution) {
CGFloat ratio = width/height;
if (ratio > 1) {
bounds.size.width = kMaxResolution;
bounds.size.height = bounds.size.width / ratio;
} else {
bounds.size.height = kMaxResolution;
bounds.size.width = bounds.size.height * ratio;
}
}
CGFloat scaleRatio = bounds.size.width / width;
UIImageOrientation orient = image.imageOrientation;
switch(orient) {
case UIImageOrientationUp:
transform = CGAffineTransformIdentity;
break;
default:
[NSException raise:NSInternalInconsistencyException
format:#"Invalid image orientation"];
}
UIGraphicsBeginImageContext(bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
CGContextScaleCTM(context, -scaleRatio, scaleRatio);
CGContextTranslateCTM(context, -height, 0);
} else {
CGContextScaleCTM(context, scaleRatio, -scaleRatio);
CGContextTranslateCTM(context, 0, -height);
}
CGContextConcatCTM(context, transform);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return returnImage;
}
But how can I crop only face from the image (Like face image in box) because for now it changes original resolution of image?

If you want to crop your image with more conveniently and more user-defined, I recommend you to use the RSKImageCropper, its github location is here:https://github.com/ruslanskorb/RSKImageCropper
Because you want to crop the face's position, so the system's default method is not satisfy your requirement, you can learn from here:https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/CameraAndPhotoLib_TopicsForIOS/Articles/PickinganItemfromthePhotoLibrary.html#//apple_ref/doc/uid/TP40010408-SW1
The Core Graphic's crop image method:CGImageCreateWithImageInRect, is not easy to confirm the rect you want, because you for get the position of the face you should do a lot of work, the RSKImageCropper may be your convenient choise.

Related

crop UIImage function not work properly when photo take from camera.?

I used crop function that crop image . It is work good when i take photo from photo library but when i use camera to take picture and crop the image. the crop function give me a wrong crop image .
My crop logic:
float zoomScale = 1.0 / [scrollView zoomScale];
CGRect rect;
rect.origin.x = [scrollView contentOffset].x * zoomScale;
rect.origin.y = [scrollView contentOffset].y * zoomScale;
rect.size.width = [scrollView bounds].size.width * zoomScale;
rect.size.height = [scrollView bounds].size.height * zoomScale;
UIImage *cropped = [self cropImage:imageView.image toRect:rect];//[UIImage imageWithCGImage:cr];
//CGImageRelease(cr);
return cropped;
static inline double radians (double degrees) {return degrees * M_PI/180;}
-(UIImage*)cropImage:(UIImage*)originalImage toRect:(CGRect)rect{
CGImageRef imageRef = CGImageCreateWithImageInRect([originalImage CGImage], rect);
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);
CGContextRef bitmap = CGBitmapContextCreate(NULL, rect.size.width, rect.size.height, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
if (originalImage.imageOrientation == UIImageOrientationLeft) {
CGContextRotateCTM (bitmap, radians(90));
CGContextTranslateCTM (bitmap, 0, -rect.size.height);
} else if (originalImage.imageOrientation == UIImageOrientationRight) {
CGContextRotateCTM (bitmap, radians(-90));
CGContextTranslateCTM (bitmap, -rect.size.width, 0);
} else if (originalImage.imageOrientation == UIImageOrientationUp) {
// NOTHING
} else if (originalImage.imageOrientation == UIImageOrientationDown) {
CGContextTranslateCTM (bitmap, rect.size.width, rect.size.height);
CGContextRotateCTM (bitmap, radians(-180.));
}
CGContextDrawImage(bitmap, CGRectMake(0, 0, rect.size.width, rect.size.height), imageRef);
CGImageRef ref = CGBitmapContextCreateImage(bitmap);
UIImage *resultImage=[UIImage imageWithCGImage:ref];
CGImageRelease(imageRef);
CGContextRelease(bitmap);
CGImageRelease(ref);
return resultImage;
}
what is the problem with my code ?
image taken from camera is not proper crop .
Please solve it .
I want whole bottle image see in first image that i have to set but when i press crop button and give me a wrong image . seein second image.

Why the PNG image resized and shows very well in UIImageView but quality not good when I draw it by CGContextDrawImage

I have a PNG (52x52) image file,if I show it in a UIImageView (16x16) , it is showed good.
But if I try to use CGContextDrawImage to draw, the quality is very bad.
Please see below detail code:
resizeImage is used to resize the image (copy from apple site).
drawStonesPng is do draw the image and called form CALayer:: drawInContext
- (UIImage*)resizeImage:(UIImage*)image toWidth:(NSInteger)width height:(NSInteger)height
{
// Create a graphics context with the target size
// On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
// On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
CGSize size = CGSizeMake(width, height);
if (NULL != UIGraphicsBeginImageContextWithOptions)
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
else
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
// Flip the context because UIKit coordinate system is upside down to Quartz coordinate system
CGContextTranslateCTM(context, 0.0, height);
CGContextScaleCTM(context, 1.0, -1.0);
// Draw the original image to the context
CGContextSetBlendMode(context, kCGBlendModeCopy);
CGContextDrawImage(context, CGRectMake(0.0, 0.0, width, height), image.CGImage);
// Retrieve the UIImage from the current context
UIImage *imageOut = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageOut;
}
-(void)drawStonesPng:(CGContextRef)ctx{
_cellWidth=16;
float x1,y1;
float f1=0.48;
// self.contentsScale = [UIScreen mainScreen].scale;
UIImage* resizedImageBlack = [self resizeImage:[UIImage imageNamed:#"blackstone52"] toWidth:_cellWidth*f1*2 height:_cellWidth*f1*2];
UIImage* resizedImageBlackShadow = [self resizeImage:[UIImage imageNamed:#"blackshadow"] toWidth:_cellWidth*f1*2 height:_cellWidth*f1*2];
CGImageRef imgBlack = [resizedImageBlack CGImage];
CGImageRef imgBlackShadow = [resizedImageBlackShadow CGImage];
CGFloat width = CGImageGetWidth(imgBlack), height = CGImageGetHeight(imgBlack);
// CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh);
// CGContextSetShouldAntialias(ctx, true);
for(int y=0; y<_boardSize; y++) {
for(int x=0; x<_boardSize; x++) {
STONE_T stone = [MyGoController getStoneType:x y:y];
if(STONE_INVALID==stone){
CGContextClosePath(ctx);
return;
}
if(stone==STONE_BLACK){
x1=(x+1)*_cellWidth-_cellWidth*f1;
y1=(y+1)*_cellWidth-_cellWidth*f1;
// CGFloat scale = _cellWidth*0.9/width;
// NSLog(#"Scale: %f\nWidth: %f\nHeight: %f", scale, width, height);
// CGContextTranslateCTM(ctx, 0, height / scale);
// CGContextScaleCTM(ctx, 1.0, -1.0);
CGFloat scale = [[UIScreen mainScreen] scale];
self.contentsScale =[[UIScreen mainScreen] scale];
NSLog(#"Scale: %f\nWidth: %f\nHeight: %f", scale, width, height);
CGContextTranslateCTM(ctx, 0, width / scale);
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextDrawImage(ctx, CGRectMake(x1+1, y1+1, width/scale,width/scale), imgBlackShadow);
CGContextDrawImage(ctx, CGRectMake(x1, y1, width/scale,width/scale), imgBlack);
}
}
}
resizedImageBlack = [self resizeImage:[UIImage imageNamed:#"whitestone52"] toWidth:_cellWidth*f1*2 height:_cellWidth*f1*2];
resizedImageBlackShadow = [self resizeImage:[UIImage imageNamed:#"whiteshadow"] toWidth:_cellWidth*f1*2 height:_cellWidth*f1*2];
imgBlack = [resizedImageBlack CGImage];
imgBlackShadow = [resizedImageBlackShadow CGImage];
//draw white stones
for(int y=0; y<_boardSize; y++) {
for(int x=0; x<_boardSize; x++) {
STONE_T stone = [MyGoController getStoneType:x y:y];
if(stone==STONE_WHITE){
x1=(x+1)*_cellWidth-_cellWidth*f1;
y1=(y+1)*_cellWidth-_cellWidth*f1;
// CGFloat scale = _cellWidth*0.9/width;
// NSLog(#"Scale: %f\nWidth: %f\nHeight: %f", scale, width, height);
// CGContextTranslateCTM(ctx, 0, height / scale);
// CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextDrawImage(ctx, CGRectMake(x1+1, y1+1, _cellWidth*f1*2,_cellWidth*f1*2), imgBlackShadow);
CGContextDrawImage(ctx, CGRectMake(x1, y1, _cellWidth*f1*2,_cellWidth*f1*2), imgBlack);
}
}
}
}
You need to set the content scale of the layer you're using :
CALayer theLayer = ....;
theLayer.contentsScale = [UIScreen mainScreen].scale

Resizing image to fit in a 320x320 imageview without loosing the quality and stretching

i am trying to resize the image in a 320x320 imageview. i am capturing the image from camera and loading from gallery also. i am using the above code to resize;
-(UIImage *)scaleAndRotateImage:(UIImage *)image max:(int)kMaxResolution
{
// NSLog(#"W=%f h=%f",self.m_initialImage.size.width,self.m_initialImage.size.height);
// int kMaxResolution = 430;
CGImageRef imgRef = image.CGImage;
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
if (width > kMaxResolution || height > kMaxResolution) {
CGFloat ratio = width/height;
if (ratio > 1) {
bounds.size.width = kMaxResolution;
bounds.size.height = bounds.size.width / ratio;
}
else {
bounds.size.height = kMaxResolution;
bounds.size.width = bounds.size.height * ratio;
}
}
CGFloat scaleRatio = bounds.size.width / width;
CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
CGFloat boundHeight;
UIImageOrientation orient = image.imageOrientation;
switch(orient) {
case UIImageOrientationUp: //EXIF = 1
transform = CGAffineTransformIdentity;
break;
case UIImageOrientationUpMirrored: //EXIF = 2
transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
break;
case UIImageOrientationDown: //EXIF = 3
transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationDownMirrored: //EXIF = 4
transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
break;
case UIImageOrientationLeftMirrored: //EXIF = 5
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;
case UIImageOrientationLeft: //EXIF = 6
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;
case UIImageOrientationRightMirrored: //EXIF = 7
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeScale(-1.0, 1.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;
case UIImageOrientationRight: //EXIF = 8
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;
default:
[NSException raise:NSInternalInconsistencyException format:#"Invalid image orientation"];
}
UIGraphicsBeginImageContext(bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
CGContextScaleCTM(context, -scaleRatio, scaleRatio);
CGContextTranslateCTM(context, -height, 0);
}
else {
CGContextScaleCTM(context, scaleRatio, -scaleRatio);
CGContextTranslateCTM(context, 0, -height);
}
CGContextConcatCTM(context, transform);
// CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
// UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
// UIGraphicsEndImageContext();
UIGraphicsBeginImageContextWithOptions(image.size, NO, 1.0);
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// NSLog(#"%f,%f",image.size.width, image.size.height);
// float ratioWidth=image.size.width/380;
// float imgWidth=image.size.width/ratioWidth;
// float tmp=image.size.height/568;
// float imgHeight=image.size.height/tmp;
if(image.size.width<image.size.height)
{
normalizedImage=[self compressMe:normalizedImage width:320 height:500];
}
else
{
// normalizedImage=[self compressMe:normalizedImage width:380 height:380];
normalizedImage=[self compressMe:normalizedImage width:340 height:320];
}
// Resize image
// UIGraphicsBeginImageContext(CGSizeMake(320, 426));
// [image drawInRect: CGRectMake(0, 0, 320, 426)];
// UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
// UIGraphicsEndImageContext();
//
// CGRect cropRect = CGRectMake(0, 55, 320, 320);
// CGImageRef imageRef = CGImageCreateWithImageInRect([smallImage CGImage], cropRect);
//
// UIImage *normalizedImage=[UIImage imageWithCGImage:imageRef];
//
// CGImageRelease(imageRef);
return normalizedImage;
}
-(UIImage*)compressMe:(UIImage*)image width:(float)width height:(float)height
{
NSLog(#"%f,%f",width,height);
// Get size of current image
CGSize size = [image size];
if( size.width == width
&& size.height == height){
return image;
}
CGSize newSize = CGSizeMake(width, height);
double ratio;
double delta;
CGPoint offset;
//make a new square size, that is the resized imaged width
CGSize sz = CGSizeMake(newSize.width, newSize.height);
//figure out if the picture is landscape or portrait, then
//calculate scale factor and offset
if (image.size.width > image.size.height) {
ratio = newSize.height / image.size.height;
delta = ratio*(image.size.width - image.size.height);
offset = CGPointMake(delta/2, 0);
sz.width=ratio*image.size.width;
} else {
ratio = newSize.width / image.size.width;
delta = ratio*(image.size.height - image.size.width);
offset = CGPointMake(0, delta/2);
}
NSLog(#"%f,%f,%f,%f",offset.x,offset.y,ratio * image.size.height,(ratio * image.size.width));
//make the final clipping rect based on the calculated values
// CGRect clipRect = CGRectMake(0, 0,
// (ratio * image.size.width-((offset.y)+offset.x)),
// ((ratio * image.size.height)-(offset.y)*2));
CGRect clipRect = CGRectMake(0,0,
(ratio * image.size.width),
(ratio * image.size.height));
// CGRect clipRect = CGRectMake(0,0,width,height);
CGSize szz = CGSizeMake((ratio * image.size.width),
(ratio * image.size.height));
//start a new context, with scale factor 0.0 so retina displays get
//high quality image
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(szz, YES, 0.0);
} else {
UIGraphicsBeginImageContext(szz);
}
UIRectClip(clipRect);
[image drawInRect:clipRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSLog(#"%f,%f",newImage.size.width,newImage.size.height);
return newImage;
}
The image is not getting resized properly, can anyone suggest me where i am lacking behind.
Thanks
Sorry I didn't read the whole code.
But since you are trying to put the image in an UIImageView, Why don't you use "contentMode" property to let the UIImageView resize the image appropriately to fit the image view

how to handle Image rotation issue in IOS image cropping

I am working on camera related app.Here I am taking image from camera and need to crop it and later fix that to image view.For cropping the image I am using OpenGL.My problem is I am after cropping the image is getting rotated 180 degrees.But this is not happening all the time.Some times I am getting the original image itself.
-(void)showResult
{
NSLog(#"showResult called" );
UIImage *imageCrop;
float scaleCrop;
if (_sourceImage.size.width >= IMAGEWIDTH)
{
scaleCrop = IMAGEWIDTH / _sourceImage.size.width;
imageCrop = [ImageCropViewController scaleImage:_sourceImage with:CGSizeMake(_sourceImage.size.width*scaleCrop, _sourceImage.size.height*scaleCrop)];
}
else
{
scaleCrop = 1;
imageCrop = _sourceImage;
}
float scale = _sourceImage.size.width / resizeImage.size.width * 2;
IplImage *iplImage = [ImageCropViewController CreateIplImageFromUIImage:imageCrop] ;
Quadrilateral rectan;
rectan.point[0].x = _touchLayer.rectan.pointA.x*scale*scaleCrop;
rectan.point[0].y = _touchLayer.rectan.pointA.y*scale*scaleCrop;
rectan.point[1].x = _touchLayer.rectan.pointB.x*scale*scaleCrop;
rectan.point[1].y = _touchLayer.rectan.pointB.y*scale*scaleCrop;
rectan.point[2].x = _touchLayer.rectan.pointC.x*scale*scaleCrop;
rectan.point[2].y = _touchLayer.rectan.pointC.y*scale*scaleCrop;
rectan.point[3].x = _touchLayer.rectan.pointD.x*scale*scaleCrop;
rectan.point[3].y = _touchLayer.rectan.pointD.y*scale*scaleCrop;
IplImage* dest = cropDoc2(iplImage,rectan);
IplImage *image = cvCreateImage(cvGetSize(dest), IPL_DEPTH_8U, dest->nChannels);
cvCvtColor(dest, image, CV_BGR2RGB);
cvReleaseImage(&dest);
tempImage = [ImageCropViewController UIImageFromIplImage:image withImageOrientation:_sourceImage.imageOrientation];
[self crop:tempImage];
cvReleaseImage(&image);
}
After that the below method is called
+ (UIImage *)UIImageFromIplImage:(IplImage *)image withImageOrientation:(UIImageOrientation)orientation
{
NSLog(#"UIImageFromIplImage called" );
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSData *data = [NSData dataWithBytes:image->imageData length:image->imageSize];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
CGImageRef imageRef = CGImageCreate(image->width, image->height, image->depth, image->depth * image->nChannels, image->widthStep, colorSpace, kCGImageAlphaNone|kCGBitmapByteOrderDefault, provider, NULL, false, kCGRenderingIntentDefault);
UIImage *ret = [UIImage imageWithCGImage:imageRef scale:1 orientation:orientation];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return ret;
}
Then I am rotating the Image as per my requirement
-(void)crop:(UIImage*)image
{
NSLog(#"crop called" );
//Adjust the image size, to scale the image to 1013 of width
float targetWidth = 1009.0f;
float scale = targetWidth / image.size.width;
float scaleheight = image.size.height * scale;
UIImage *imageToSent = [ImageCropViewController scaleImage:image with:CGSizeMake(targetWidth, scaleheight)];
if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft)
{
NSLog(#"###########Image orientation is UIInterfaceOrientationLandscapeLeft###########");
imageToSent = [[UIImage alloc] initWithCGImage:imageToSent.CGImage scale:1.0f orientation:UIImageOrientationDown];
}
NSData *imageData = UIImageJPEGRepresentation(imageToSent,0.75);
NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0];
NSString *caldate = [now description];
appDelegate.imagefilePath= [NSString stringWithFormat:#"%#/%#.jpg", DOCUMENTS_FOLDER,caldate];
[imageData writeToFile:appDelegate.imagefilePath atomically:YES];
appDelegate.cropimage=imageToSent;
}
I am not getting where it was gone wrong.It is killing my time.Please help me.
Thanks in advance
I have this code for cropping. Why are you using openGL. Here is my code.
- (UIImage *)cropImage : (UIImage*)myImage withRect:(CGRect)rect
{
CGImageRef imageRef = CGImageCreateWithImageInRect([myImage CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return img;
}
Just call this method whenever you want to crop your image. Also When you take an image from Camera or gallery(image taken from native camera app) you will get a rotated image. Use this code to get it back the original image.
//----rotate image if picked from gallery or camera----//
- (UIImage *)scaleAndRotateImage:(UIImage *)image {
NSLog(#"scaleAndRotateImage");
static int kMaxResolution = 640; // this is the maximum resolution that you want to set for an image.
CGImageRef imgRef = image.CGImage;
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
if (width > kMaxResolution || height > kMaxResolution) {
CGFloat ratio = width/height;
if (ratio > 1) {
bounds.size.width = kMaxResolution;
bounds.size.height = bounds.size.width / ratio;
} else {
bounds.size.height = kMaxResolution;
bounds.size.width = bounds.size.height * ratio;
}
}
CGFloat scaleRatio = bounds.size.width / width;
CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
CGFloat boundHeight;
UIImageOrientation orient = image.imageOrientation;
switch(orient) {
case UIImageOrientationUp:
transform = CGAffineTransformIdentity;
break;
case UIImageOrientationUpMirrored:
transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
break;
case UIImageOrientationDown:
transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationDownMirrored:
transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
break;
case UIImageOrientationLeftMirrored:
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;
case UIImageOrientationLeft:
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;
case UIImageOrientationRightMirrored:
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeScale(-1.0, 1.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;
case UIImageOrientationRight:
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;
default:
[NSException raise:NSInternalInconsistencyException
format:#"Invalid image orientation"];
}
UIGraphicsBeginImageContext(bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
CGContextScaleCTM(context, -scaleRatio, scaleRatio);
CGContextTranslateCTM(context, -height, 0);
} else {
CGContextScaleCTM(context, scaleRatio, -scaleRatio);
CGContextTranslateCTM(context, 0, -height);
}
CGContextConcatCTM(context, transform);
CGContextDrawImage(UIGraphicsGetCurrentContext(),
CGRectMake(0, 0, width, height), imgRef);
UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return returnImage;
}
Hope I helped.

Merge Two UIImage that are Rotated & Scaled

I'am doing an app something like this: You load a photo and you put images over it, like balloons, etc..
When I try to merge one of this over images with only resize it works fine. Like 10px more than it should be but no problem.
The problem comes when you rotate the image [UIImageView] it appears much bigger that the image its, I try allot of things and nothing. I leave the code. I hope someone could help.
Note: The image size its inside UIImageView, then multiplied it by the scale of the main image
- (UIImage *)mergeImage:(UIImageView *)mainImage withImageView:(UIImageView *)imageView {
UIImage *temp = imageView.image;
UIImage *tempMain = mainImage.image;
CGFloat mainScale = [self imageViewScaleFactor:mainImage];
CGFloat tempScale = 1/mainScale;
NSLog(#"%f", tempScale);
//Rotate UIIMAGE
UIGraphicsBeginImageContext(temp.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformTranslate(transform, temp.size.width/2, temp.size.height/2);
CGFloat angle = atan2(imageView.transform.b, imageView.transform.a);
transform = CGAffineTransformRotate(transform, angle);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
CGContextConcatCTM(ctx, transform);
// Draw the image into the context
CGContextDrawImage(ctx, CGRectMake(-temp.size.width/2, -temp.size.height/2, temp.size.width, temp.size.height), temp.CGImage);
// Get an image from the context
temp = [UIImage imageWithCGImage: CGBitmapContextCreateImage(ctx)];
NSLog(#"%f %f %f", mainScale, mainImage.frame.size.width, mainImage.frame.size.height);
UIGraphicsBeginImageContextWithOptions(tempMain.size, NO, 1.0f);
//Get imageView size & position
NSLog(#"%f %f %f %f", imageView.frame.origin.x, imageView.frame.origin.y, imageView.frame.size.width, imageView.frame.size.height);
CGFloat offsetX = 0;
CGFloat offsetY = -44;
if (tempMain.size.height > tempMain.size.width) {
offsetX = ((tempMain.size.width * mainScale) - 320)/2;
}else{
offsetY = ((tempMain.size.height * mainScale) - 416)/2;
offsetY -= 44;
}
CGFloat imageViewX = (imageView.frame.origin.x + offsetX) * tempScale;
CGFloat imageViewY = (imageView.frame.origin.y + offsetY) * tempScale;
CGFloat imageViewW = imageView.frame.size.width * tempScale;
CGFloat imageViewH = imageView.frame.size.height * tempScale;
CGRect tempRect = CGRectMake(imageViewX, imageViewY, imageViewW, imageViewH);
[tempMain drawAtPoint:CGPointZero];
[temp drawInRect:tempRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Thanks
This is the solution that works for me
Merging a previosly rotated by gesture UIImageView with another one. WYS is not WYG
I just take a photo to the main screen and then crop it to the size of the photo, its faster, and clean. and the resolution it ok if the apps runs in retina in a normal device isn't too good. And you need to prepare that code to work in retina & non-retina

Resources