按比例调整UIImage的大小然后裁剪

3
我正在使用这段代码调整相机拍摄的图像大小。我将它按比例缩小为缩略图,但是接下来我想将它裁剪成60x60的正方形格式。我尝试了以下方法:
CGImageRef imageRef = CGImageCreateWithImageInRect(CGImage, rect); 

但是我没有成功让它正常工作。如何使用核心图形来实现这个?

- (UIImage *) resizeCapturedImage:(UIImage *) img toWidth:(float) w{

    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(NULL,w,w, 8, 0, colorspace,kCGImageAlphaPremultipliedFirst);

    CGContextDrawImage(ctx, CGRectMake(0, 0, w,img.size.width*w/img.size.height), img.CGImage);
    CGImageRef thumb = CGBitmapContextCreateImage(ctx);
    UIImage *final = [UIImage imageWithCGImage:thumb scale:1.0 orientation:UIImageOrientationRight];

    return final;
}
2个回答

13

这里我提供了裁剪和调整图像大小的逻辑,您可以根据需求使用。

获取裁剪后的图像:

UIImage *croppedImg = nil;
CGRect cropRect = CGRectMake(AS YOu Need); // set frame as you need
croppedImg = [self croppIngimageByImageName:self.imageView.image toRect:cropRect];
以下方法返回UIImage按您所需的图像尺寸
- (UIImage *)croppIngimageByImageName:(UIImage *)imageToCrop toRect:(CGRect)rect
    {
        //CGRect CropRect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height+15);

        CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
        UIImage *cropped = [UIImage imageWithCGImage:imageRef];
        CGImageRelease(imageRef);

        return cropped;
    }

这里您可以获取由上述方法返回的裁剪图像;

或者调整大小

并且还可以使用以下具有特定高度宽度的图像的调整大小方法:

+ (UIImage*)resizeImage:(UIImage*)image withWidth:(CGFloat)width withHeight:(CGFloat)height
{
    CGSize newSize = CGSizeMake(width, height);
    CGFloat widthRatio = newSize.width/image.size.width;
    CGFloat heightRatio = newSize.height/image.size.height;

    if(widthRatio > heightRatio)
    {
        newSize=CGSizeMake(image.size.width*heightRatio,image.size.height*heightRatio);
    }
    else
    {
        newSize=CGSizeMake(image.size.width*widthRatio,image.size.height*widthRatio);
    }


    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

这个方法返回一个具有特定大小的NewImage


使用CGFloat,而不是 float 或者 int - Guy Kogus
这有很多内容。问题在于你在数据类型之间进行了隐式转换。这可能会导致不可预测的值,例如当你将一个float类型的3.5转换为int时,结果可能是4(如果四舍五入),但更有可能将其截断为3。你希望尽可能保持一致使用数据类型,如果必须进行转换,则要明确地进行,并且有充分的理由。你介意我编辑你的答案以展示应该是什么吗? - Guy Kogus
另一个可能出现的问题示例是值的丢失。如果您有像 int 这样可以存储 +/-65535 值并将其转换为 short 的变量,而 short 只能存储 +/-32767 值,则会丢失高位值。 - Guy Kogus
不是 float,而是 CGFloat ;) - Guy Kogus
1
抱歉,我犯了一个错误 :( - iPatel
显示剩余2条评论

4

想要指出的是,为了提高性能,最好先裁剪图像,然后再调整裁剪后的部分大小,而不是先调整整个图像的大小,然后再进行裁剪。特别是对于较大的图像。


你测试过先裁剪后调整大小比另一种方式占用更少的内存吗?我刚刚用工具测试了一下,每次在裁剪之前调整大小会消耗大约20%的内存(2448,3264)。 - Islam
如果您在iOS上使用CIImage或类似的东西,那么它可能会在幕后执行一些优化,例如堆叠操作。从概念上讲,调整大小2048 X 1024像素的图像比调整大小320 X 240像素的图像需要更长的时间。 - Adam Freeman
我正在使用AVCam示例拍照,并尝试创建一个正方形图像(例如从2448x3264的图像中创建640x640的图像)。当我尝试裁剪为2448x2448,然后调整大小为640x640时,它占用约65Mb的空间;而当我先调整大小再裁剪时,它只占用约53Mb的空间。 - Islam
你知道一种同时执行这两个操作的最佳方法吗? - Islam
让我们在聊天中继续这个讨论 - Islam
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接