旋转图像并将图像保存为 Rotated 状态
Posted
技术标签:
【中文标题】旋转图像并将图像保存为 Rotated 状态【英文标题】:Rotate image and save the image with the Rotated state 【发布时间】:2011-07-07 08:45:54 【问题描述】:我想用 UIslider 控件旋转图像。
我已经用下面的函数做到了
- (void)rotateImage:(UIImageView *)图像持续时间:(NSTimeInterval)持续时间 曲线:(int)曲线度:(CGFloat)度 //设置动画 [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:duration]; [UIView setAnimationCurve:curve]; [UIView setAnimationBeginsFromCurrentState:YES];// The transform matrix
CGAffineTransform transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(degrees));
image.transform = transform;
// Commit the changes
[UIView commitAnimations];
通过使用此功能,它将完美运行 但问题是我无法保存旋转的图像参考。 我必须使用旋转后的图像进行进一步处理。
那么如何保存旋转位置的图像呢?
请帮我解决这个问题
谢谢
【问题讨论】:
【参考方案1】:我找到了我的问题的解决方案
使用下面的这个方法
- (UIImage*)upsideDownBunny:(CGFloat)radians withImage:(UIImage*)testImage
__block CGImageRef cgImg;
__block CGSize imgSize;
__block UIImageOrientation orientation;
dispatch_block_t createStartImgBlock = ^(void)
// UIImages should only be accessed from the main thread
UIImage *img =testImage
imgSize = [img size]; // this size will be pre rotated
orientation = [img imageOrientation];
cgImg = CGImageRetain([img CGImage]); // this data is not rotated
;
if([NSThread isMainThread])
createStartImgBlock();
else
dispatch_sync(dispatch_get_main_queue(), createStartImgBlock);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
// in ios4+ you can let the context allocate memory by passing NULL
CGContextRef context = CGBitmapContextCreate( NULL,
imgSize.width,
imgSize.height,
8,
imgSize.width * 4,
colorspace,
kCGImageAlphaPremultipliedLast);
// rotate so the image respects the original UIImage's orientation
switch (orientation)
case UIImageOrientationDown:
CGContextTranslateCTM(context, imgSize.width, imgSize.height);
CGContextRotateCTM(context, -radians);
break;
case UIImageOrientationLeft:
CGContextTranslateCTM(context, 0.0, imgSize.height);
CGContextRotateCTM(context, 3.0 * -radians / 2.0);
break;
case UIImageOrientationRight:
CGContextTranslateCTM(context,imgSize.width, 0.0);
CGContextRotateCTM(context, -radians / 2.0);
break;
default:
// there are mirrored modes possible
// but they aren't generated by the iPhone's camera
break;
// rotate the image upside down
CGContextTranslateCTM(context, +(imgSize.width * 0.5f), +(imgSize.height * 0.5f));
CGContextRotateCTM(context, -radians);
//CGContextDrawImage( context, CGRectMake(0.0, 0.0, imgSize.width, imgSize.height), cgImg );
CGContextDrawImage(context, (CGRect).origin.x = -imgSize.width* 0.5f , .origin.y = -imgSize.width* 0.5f , .size.width = imgSize.width, .size.height = imgSize.width, cgImg);
// grab the new rotated image
CGContextFlush(context);
CGImageRef newCgImg = CGBitmapContextCreateImage(context);
__block UIImage *newImage;
dispatch_block_t createRotatedImgBlock = ^(void)
// UIImages should only be accessed from the main thread
newImage = [UIImage imageWithCGImage:newCgImg];
;
if([NSThread isMainThread])
createRotatedImgBlock();
else
dispatch_sync(dispatch_get_main_queue(), createRotatedImgBlock);
CGColorSpaceRelease(colorspace);
CGImageRelease(newCgImg);
CGContextRelease(context);
return newImage;
用
调用这个方法 UIImage *rotated2 = [self upsideDownBunny:rotation];
其中旋转为 0 到 360 之间的滑块值。
现在我们可以保存旋转后的状态了。
【讨论】:
【参考方案2】:我尝试了上面的代码,它可以工作,但仅适用于 SQUARE 图像,这是另一个可行的解决方案,它将重新绘制图像并保持正确的宽度/高度:
- (UIImage *) rotatedImage:(UIImage *)imageRotation and:(CGFloat) rotation
// Calculate Destination Size
CGAffineTransform t = CGAffineTransformMakeRotation(rotation);
CGRect sizeRect = (CGRect) .size = imageRotation.size;
CGRect destRect = CGRectApplyAffineTransform(sizeRect, t);
CGSize destinationSize = destRect.size;
// Draw image
UIGraphicsBeginImageContext(destinationSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, destinationSize.width / 2.0f, destinationSize.height / 2.0f);
CGContextRotateCTM(context, rotation);
[imageRotation drawInRect:CGRectMake(-imageRotation.size.width / 2.0f, -imageRotation.size.height / 2.0f, imageRotation.size.width, imageRotation.size.height)];
// Save image
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
这里的旋转参数是以弧度给出的。您可以通过将其添加到您的函数上方(或直接在您的 .m 文件中)来执行转换
#define M_PI 3.14159265358979323846264338327950288 /* pi */
#define DEGREES_TO_RADIANS(angle) (angle / 180.0 * M_PI)
最后,我用动画来称呼它:
[UIView animateWithDuration:0.5f delay:0 options:UIViewAnimationCurveEaseIn animations:^
//Only used for the ANIMATION of the uiimage
imageView.transform = CGAffineTransformRotate(editorPad.transform, DEGREES_TO_RADIANS(90));
completion:^(BOOL finished)
// Workaround : Need to set previous transformation back or the next step will turn the image more
imageView.transform = CGAffineTransformRotate(imageView.transform, DEGREES_TO_RADIANS(-90));
imageView.image = [self imageView.image and:DEGREES_TO_RADIANS(90)];
];
我希望这也能有所帮助!
干杯。
【讨论】:
【参考方案3】:进一步处理的一种方法是按顺序应用更多转换,例如:
CGAffineTransform transform = CGAffineTransformScale(previousTransform, newScale, newScale);
在这种情况下,您将对旋转的图像应用缩放。
如果您需要保存这些信息以便以后能够重做转换,您可以简单地存储旋转角度、缩放因子(在我的示例中),然后再次构建转换。
您还可以考虑将您的 CGAffineTransform
存储在您的类或其他机制的 ivar 中。
编辑:
如果保存是指保存到文件,则可以使用以下代码将视图转换为图像:
NSData *data;
NSBitmapImageRep *rep;
rep = [self bitmapImageRepForCachingDisplayInRect:[self frame]];
[self cacheDisplayInRect:[self frame] toBitmapImageRep:rep];
data = [rep TIFFRepresentation];
然后将 NSData 保存到文件中
对于 PNG:
UIGraphicsBeginImageContext(self.bounds.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* image1 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *imageData = UIImagePNGRepresentation(image1);
[imageData writeToFile:filePath atomically:YES];
【讨论】:
我在旋转图像时没有问题,但问题是我必须保存旋转后的图像。那我该怎么做呢? 将图片保存在旋转位置。 我必须将旋转后的图像保存在 .png 文件中。【参考方案4】:您可以将旋转后的图像渲染成另一张图像:
UIGraphicsBeginImageContext(aCGRectToHoldYourImage);
CALayer* layer = myRotatedImageView.layer;
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
然后从中获取 PNG 数据并将其保存到文件中
NSData* myPNGData = [viewImage UIImagePNGRepresentation];
[myPNGData writeToFile:@"aFileName.png" atomically:YES];
附带条件,我在 *** 中输入了这个,而不是编译器 :-)
【讨论】:
【参考方案5】:保存你的 UIImageView 的转换值,并在下次你想使用这个 UIImageView 甚至另一个 UIImageView 时应用这个转换值。
【讨论】:
以上是关于旋转图像并将图像保存为 Rotated 状态的主要内容,如果未能解决你的问题,请参考以下文章