更改UIImage的NSData大小 - 压缩和调整UIImage的最大兆字节Mb限制 [英] Change NSData Size of a UIImage - Compress And Resize UIImage With a Maximum Megabyte Mb limit

查看:126
本文介绍了更改UIImage的NSData大小 - 压缩和调整UIImage的最大兆字节Mb限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用户上传的UIImage。

I have a UIImage that the user has uploaded.

如果图像数据超过10Mb,我怎样才能将其调整为最大10 Mb?到目前为止,我发现数据大小调整最接近的是:

If the image data is more than 10Mb how can I resize it to a maximum of 10 Mb? So far the closest thing I've found for data resizing is this:

NSData * imageData = UIImageJPEGRepresentation(theUploadedImage.image,0.5f);

但我似乎无法控制文件大小的Mb ...只是JPG表示中的第二个参数(图像质量漂浮)

But I don't seem to have control over the Mb of file size... just over the second parameter in the JPG representation (image quality float)

推荐答案

必须创建我自己的函数来压缩图像尽可能小,如果它仍然是超过我的最大尺寸然后它调整大小,保留并再次开始压缩迭代。如果图像超过文件大小,这可以使图像尽可能接近目标最大图像文件大小。还包括1024次迭代后的故障保护。 (这应该永远不会持续超过一分钟(但这是一个永远不会出现的情况......谁在iPhone上使用的是GB的图像?哈哈))...

Had to create my own function that compresses an image as small as it can get, and if it's still over my "max size" then it resizes, reserves and begins the compression iteration again. This does a fairly good job of getting the image as close as possible to target "max image file size" if it's over the file size. Also includes a failsafe after 1024 iterations. (Which should never last longer than a minute (but that's a scenario that would never occour... who uses images that are gigabytes on an iPhone? Haha))...

-(void)shrinkImage {


    //IMPORTANT!!! THIS CODE WAS CREATED WITH "ARC" IN MIND... DO NOT USE WITHOUT ARC UNLESS YOU ALTER THIS CODE TO MANAGE MEMORY


    float compressionVal = 1.0;
    float maxVal = 9.7;//MB

    UIImage *compressedImage = theUploadedImage.image; //get UIImage from imageView

    int iterations = 0;
    int totalIterations = 0;

    float initialCompressionVal = 0.00000000f;

    while (((((float)(UIImageJPEGRepresentation(compressedImage, compressionVal).length))/(1048576.000000000f)) > maxVal) && (totalIterations < 1024)) {

        NSLog(@"Image is %f MB", (float)(((float)(UIImageJPEGRepresentation(compressedImage, compressionVal)).length)/(1048576.000000f)));//converts bytes to MB

        compressionVal = (((compressionVal)+((compressionVal)*((float)(((float)maxVal)/((float)(((float)(UIImageJPEGRepresentation(compressedImage, compressionVal).length))/(1048576.000000000f)))))))/(2));
        compressionVal *= 0.97;//subtracts 3% of it's current value just incase above algorithm limits at just above MaxVal and while loop becomes infinite.

        if (initialCompressionVal == 0.00000000f) {
            initialCompressionVal = compressionVal;
        }

        iterations ++;

        if ((iterations >= 3) || (compressionVal < 0.1)) {
            iterations = 0;
            NSLog(@"%f", compressionVal);

            compressionVal = 1.0f;


            compressedImage = [UIImage imageWithData:UIImageJPEGRepresentation(compressedImage, compressionVal)];



            float resizeAmount = 1.0f;
            resizeAmount = (resizeAmount+initialCompressionVal)/(2);//percentage
            resizeAmount *= 0.97;//3% boost just incase image compression algorithm reaches a limit.
            resizeAmount = 1/(resizeAmount);//value
            initialCompressionVal = 0.00000000f;


            UIView *imageHolder = [[UIView alloc] initWithFrame:CGRectMake(0,0,(int)floorf((float)(compressedImage.size.width/(resizeAmount))), (int)floorf((float)(compressedImage.size.height/(resizeAmount))))];//round down to ensure frame isnt larger than image itself

            UIImageView *theResizedImage = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,(int)ceilf((float)(compressedImage.size.width/(resizeAmount))), (int)ceilf((float)(compressedImage.size.height/(resizeAmount))))];//round up to ensure image fits
            theResizedImage.image = compressedImage;


            [imageHolder addSubview:theResizedImage];


            UIGraphicsBeginImageContextWithOptions(CGSizeMake(imageHolder.frame.size.width, imageHolder.frame.size.height), YES, 1.0f);
            CGContextRef resize_context = UIGraphicsGetCurrentContext();
            [imageHolder.layer renderInContext:resize_context];
            compressedImage = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();


            //after 3 compressions, if we still haven't shrunk down to maxVal size, apply the maximum compression we can, then resize the image (90%?), then re-start the process, this time compressing the compressed version of the image we were checking.

            NSLog(@"resize");
        }

        totalIterations ++;

    }

    if (totalIterations >= 1024) {
        NSLog(@"Image was too big, gave up on trying to re-size");//too many iterations failsafe. Gave up on trying to resize.
    } else {

        NSData *imageData = UIImageJPEGRepresentation(compressedImage, compressionVal);
        NSLog(@"FINAL Image is %f MB ... iterations: %i", (float)(((float)imageData.length)/(1048576.000000f)), totalIterations);//converts bytes to MB

        theUploadedImage.image = [UIImage imageWithData:imageData];//save new image to UIImageView.

    }
}

这篇关于更改UIImage的NSData大小 - 压缩和调整UIImage的最大兆字节Mb限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆