Не так давно натолкнулся на проблему правильно повернуть картинку на
нужный угол. Чаще всего это 90,180 градусов. Причем проблема заключалась
не только в том, что бы развернуть картинку для пользователя на экране
IPhone, а и сохранить изменения в графическом контексте, что бы
запомнить эту трансформацию. Перебрав кучу методов я остановился на
более простом и менее нагрузочном для системе методе. Данный способ не
обрежет картинку не по сторонам ни по высоте или ширине, что
немаловажно.
И так приступим. Подразумевается что у вас уже есть проект с размещенным на ViewVontroller-е вашей UIImageView куда вы будете показывать картинку до и полсе разворота. Поэтому я опишу лишь методы по работе с самим изображением.
Итак в методе viewDidLoad я подгружаю картинку из проекта
Теперь релазуем два метода для переворота картинки вправо и влево:
Итак мы видим, что в обоих случаях вызывается один и тот же метод -(UIImage*)imageByRotatingImage:(UIImage*)initImage fromImageOrientation:(UIImageOrientation)orientation только с разным параметром вконце. Он то как раз и указывает на ориентацию изображения в которую необходимо повернуть картинку. Взял я его гдето на просторах интернетов и немножко окрасивил для понятного использования. Перед просмотром листинга кода метода хочу сказать, что перед его вызовом подразумевается, что текущая картинка имеет ориентацию UIImageOrientationUp.
Итак сам метод:
И так приступим. Подразумевается что у вас уже есть проект с размещенным на ViewVontroller-е вашей UIImageView куда вы будете показывать картинку до и полсе разворота. Поэтому я опишу лишь методы по работе с самим изображением.
Итак в методе viewDidLoad я подгружаю картинку из проекта
UIImage *img = [UIImage imageNamed:@"test.png"];где mainimage это ваш UIImageView
mainimage.image = img;
Теперь релазуем два метода для переворота картинки вправо и влево:
-(void) RotateToLeft{Конечно вы можете написать эти методы как -(IBAction) и привязать вызов к кнопкам, но это не слишком сложно, что бы тратить на это время в этой статье
mainimage.image = [self imageByRotatingImage:img fromImageOrientation:UIImageOrientationLeft];
}
-(void)RotateToRight{
mainimage.image = [self imageByRotatingImage:img fromImageOrientation:UIImageOrientationRight];
}
Итак мы видим, что в обоих случаях вызывается один и тот же метод -(UIImage*)imageByRotatingImage:(UIImage*)initImage fromImageOrientation:(UIImageOrientation)orientation только с разным параметром вконце. Он то как раз и указывает на ориентацию изображения в которую необходимо повернуть картинку. Взял я его гдето на просторах интернетов и немножко окрасивил для понятного использования. Перед просмотром листинга кода метода хочу сказать, что перед его вызовом подразумевается, что текущая картинка имеет ориентацию UIImageOrientationUp.
Итак сам метод:
-(UIImage*)imageByRotatingImage:(UIImage*)initImage fromImageOrientation:(UIImageOrientation)orientationВо время выполнения этого метода может быть некая задержка в приложении, так как идёт выделение памяти и устройство в отличии от эмулятора может слегка притормозить свою активность, поэтому нужно быть готовым к этому. Итак мы имеем универсальный метод по развороту картинки на 90 и 180 градусов в любую сторону, а также возможность зеркально отобразить изображения. При этом сохраняя его в контексте. Чем это лучше чем просто трансформация в виде анимации? Потому, что после например анимированного траснформа поворота мы получим картинку повернутую на 90 градусов, но в контексте она останется в прежнем состоянии. И при повторном выполнении трансформации мы получим тот же результат – картинку развернутую на 90 градусов, а не на 180 как задумывалось.
{
CGImageRef imgRef = initImage.CGImage;
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
CGFloat boundHeight;
UIImageOrientation orient = orientation;
switch(orient) {
case UIImageOrientationUp: //EXIF = 1
return initImage; //если прислать в качестве параметра orientation – UIImageOrientationUp метод вернёт саму картинку целой и невредмой
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 – Перевернуть влево -90 градусов
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 – Вправо тоесть +90 градусов по часовой стрелке
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"];
}
// Вот тут создается графический контекст
CGContextRef context = NULL;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
bitmapBytesPerRow = (bounds.size.width * 4);
bitmapByteCount = (bitmapBytesPerRow * bounds.size.height);
bitmapData = malloc( bitmapByteCount );
if (bitmapData == NULL)
{
return nil;
}
CGColorSpaceRef colorspace = CGImageGetColorSpace(imgRef);
context = CGBitmapContextCreate (bitmapData,bounds.size.width,bounds.size.height,8,bitmapBytesPerRow,
colorspace,kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorspace);
if (context == NULL)
// если неполучилось создать контекст по какой либо причине отдатим nil
return nil;
CGContextScaleCTM(context, -1.0, -1.0);
CGContextTranslateCTM(context, -bounds.size.width, -bounds.size.height);
CGContextConcatCTM(context, transform);
//Отрисовка изображения в графический контекст в памяти
CGContextDrawImage(context, CGRectMake(0,0,width, height), imgRef);
CGImageRef imgRef2 = CGBitmapContextCreateImage(context);
CGContextRelease(context);
free(bitmapData);
UIImage * image = [UIImage imageWithCGImage:imgRef2 scale:initImage.scale orientation:UIImageOrientationUp];
NSData *newimageData = UIImageJPEGRepresentation(image,1.0);
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:newimageData forKey:@"chosed_image_data"];
CGImageRelease(imgRef2);
return image;
}
Комментариев нет:
Отправить комментарий