iOS图片压缩上传

需求

很多时候我们上传图片经常遇到一些问题,要不就是图片质量变差,要不就是图片太大等等问题。这里,我找到了一个算是目前比较符合需求的解决方案。在原有基础上增加了动态压缩系数,改写成Swift版本。

实现思路

先调整分辨率,分辨率可以自己设定一个值,大于的就缩小到这分辨率,小余的就保持原本分辨率。然后再根据图片最终大小来设置压缩比,比如传入maxSize = 30KB,最终计算大概这个大小的压缩比。基本上最终出来的图片数据根据当前分辨率能保持差不多的大小同时不至于太模糊,跟微信,微博最终效果应该是差不多的,代码仍然有待优化!

实现代码

    // MARK: - 降低质量
    func resetSizeOfImageData(source_image: UIImage, maxSize: Int) -> NSData {
        //先调整分辨率
        var newSize = CGSizeMake(source_image.size.width, source_image.size.height)

        let tempHeight = newSize.height / 1024
        let tempWidth  = newSize.width / 1024

        if tempWidth > 1.0 && tempWidth > tempHeight {
            newSize = CGSizeMake(source_image.size.width / tempWidth, source_image.size.height / tempWidth)
        }
        else if tempHeight > 1.0 && tempWidth < tempHeight {
            newSize = CGSizeMake(source_image.size.width / tempHeight, source_image.size.height / tempHeight)
        }

        UIGraphicsBeginImageContext(newSize)
        source_image.drawAsPatternInRect(CGRectMake(0,0,newSize.width,newSize.height))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        //先判断当前质量是否满足要求,不满足再进行压缩
        var finallImageData = UIImageJPEGRepresentation(newImage,1.0)
        let sizeOrigin      = Int64((finallImageData?.length)!)
        let sizeOriginKB    = Int(sizeOrigin / 1024)
        if sizeOriginKB <= maxSize {
            return finallImageData!
        }

        //保存压缩系数
        let compressionQualityArr = NSMutableArray()
        let avg = CGFloat(1.0/250)
        var value = avg

        for var i = 250; i>=1; i-- {
            value = CGFloat(i)*avg
            compressionQualityArr.addObject(value)
        }

        //调整大小
        //说明:压缩系数数组compressionQualityArr是从大到小存储。
        //思路:折半计算,如果中间压缩系数仍然降不到目标值maxSize,则从后半部分开始寻找压缩系数;反之从前半部分寻找压缩系数
        finallImageData = UIImageJPEGRepresentation(newImage, CGFloat(compressionQualityArr[125] as! NSNumber))
        if Int(Int64((UIImageJPEGRepresentation(newImage, CGFloat(compressionQualityArr[125] as! NSNumber))?.length)!)/1024) > maxSize {
            //从后半部分开始
            for idx in 126..<250 {
                let value = compressionQualityArr[idx]
                let sizeOrigin   = Int64((finallImageData?.length)!)
                let sizeOriginKB = Int(sizeOrigin / 1024)
                print("当前降到的质量:\(sizeOriginKB)")
                if sizeOriginKB > maxSize {
                    print("\(idx)----\(value)")
                    finallImageData = UIImageJPEGRepresentation(newImage, CGFloat(value as! NSNumber))
                } else {
                    break
                }
            }
        } else {
            //从前半部分开始
            for idx in 0..<125 {
                let value = compressionQualityArr[idx]
                let sizeOrigin   = Int64((finallImageData?.length)!)
                let sizeOriginKB = Int(sizeOrigin / 1024)
                print("当前降到的质量:\(sizeOriginKB)")
                if sizeOriginKB > maxSize {
                    print("\(idx)----\(value)")
                    finallImageData = UIImageJPEGRepresentation(newImage, CGFloat(value as! NSNumber))
                } else {
                    break
                }
            }
        }
        return finallImageData!
    }


再一次感谢您花费时间阅读这篇文章!

微博: @Danny_吕昌辉
博客: SuperDanny

时间: 2016-02-04

iOS图片压缩上传的相关文章

移动前端—图片压缩上传实践

 此前有同事跟我聊过关于移动端用canvas压缩图片后再上传的功能,最近有了点空闲时间,所以就实践了一下.demo效果链接在文章底部贴出. 在做移动端图片上传的时候,用户传的都是手机本地图片,而本地图片一般都相对比较大,拿iphone6来说,平时拍很多图片都是一两M的,如果直接这样上传,那图片就太大了,如果用户用的是移动流量,完全把图片上传显然不是一个好办法. 目前来说,HTML5的各种新API都在移动端的webkit上得到了较好的 实现.根据查看caniuse,本demo里使用到的FileRe

Android图片压缩上传之基础篇_Android

在android程序开发中我们经常见到需要上传图片的场景,在这里有个技术点,需要把图片压缩处理,然后再进行上传.这样可以减少流量的消耗,提高图片的上传速度等问题. 关于android如何压缩,网上的资料也是很多,但大多数都是代码片段,讲解压缩步骤,而没有一个实用的工具类库.那么如何将压缩算法封装成一个实用工具库呢?其中会遇到些什么问题,比如: 1.需要压缩的图片有多少 2.压缩后的图片是覆盖还是保存到另外的目录 3.如果是另存目录需要将原始图片删除吗 4.如果改变压缩后的图片的尺寸大小是按照原图

Android图片压缩上传之基础篇

在android程序开发中我们经常见到需要上传图片的场景,在这里有个技术点,需要把图片压缩处理,然后再进行上传.这样可以减少流量的消耗,提高图片的上传速度等问题. 关于android如何压缩,网上的资料也是很多,但大多数都是代码片段,讲解压缩步骤,而没有一个实用的工具类库.那么如何将压缩算法封装成一个实用工具库呢?其中会遇到些什么问题,比如: 1.需要压缩的图片有多少 2.压缩后的图片是覆盖还是保存到另外的目录 3.如果是另存目录需要将原始图片删除吗 4.如果改变压缩后的图片的尺寸大小是按照原图

HTML5实现图片压缩上传功能

上篇文章中提到移动端上传图片,我们知道现在流量还是挺贵的,手机的像素是越来越高,拍个照动不动就是好几M,伤不起.虽然客户端可以轻轻松松实现图片压缩再上传,但是我们的应用还可能在浏览器里面打开,怎么办呢,图片压缩.受以前PC上的开发思维影响,尼玛js哪有权限去操作文件,哪有资格压缩图片啊,搞不了,你们客户端去整吧.只能说自己还是有些井底之蛙了.在HTML5的影响下,前端能干的事情越来越多了,开发的功能逼格也越来越高了,H5万岁!前端的魅力也在这,过去不可能的并不意味现在.以后不可能,努力吧,骚年!

ios中摄像头/相册获取图片,压缩图片,上传服务器方法总结

这几天在搞iphone上面一个应用的开发,里面有需要摄像头/相册编程和图片上传的问题,在这里总结一下. [部分知识] iphone中图像通常存储在4个地方[相册.应用程序包.沙盒.Internet],通过这4个源,我们就可以存取应用图片. 相册 iphone的相册包含摄像头胶卷+用户计算机同步的部分照片.用户可以通过UIImagePickerController类提供的交互对话框来从相册中选择图像.但是,注意:相册中的图片机器路径无法直接从应用程序访问,只能通过终端用户去选择和使用相册图片 应用

手机页面利用canvas压缩图片再上传服务器,谷歌和微信内置浏览器可以华为自带浏览器却不行

问题描述 手机页面利用canvas压缩图片再上传服务器,谷歌和微信内置浏览器可以华为自带浏览器却不行 如题,先利用canvas压缩图片,再通过ajaxFileUpload等把图片传到服务器,canvas.toDataURL(""image/jpeg"" 0.2);明明是jpeg了,在谷歌和微信内置浏览器也可以实现,但是用华为机自带的浏览器测试时,却强制性的变成png,压缩的图片也有很大缺失,变成一大块黑色.求高手指点. 解决方案 查看下 华为浏览器的内核

java-多个图片一起上传,压缩并且用流形式保存,并不覆盖,读取的时候按照偏移量来取

问题描述 多个图片一起上传,压缩并且用流形式保存,并不覆盖,读取的时候按照偏移量来取 5C java 现在需要多个图片一起上传,后台压缩后,用流文件进行保存,每次新传的都保存到这个流文件内,并且不覆盖,读取的时候按照偏移量来取,着急着急,求源码!求指导!

压缩-上传经过canvas处理的图片!!!

问题描述 上传经过canvas处理的图片!!! 用canvas对图片进行压缩,然后用ajax post到后台,后台把图片放到本地的磁盘里,但是最后图片打开之后是空的,里面什么内容都没有..请大神看看原因. 下面是我的关键部分的代码 ajax部分 php部分 在php echo $img那里能返回图编的编码,如下 经过base64_decode解码之后的$data全部都是这样的 最后在E盘打开经过file_put_content处理的图片是一片空白 解决方案 20150129 百度Ueditor

详解IOS图片压缩处理_IOS

前言  1.确图片的压缩的概念: "压" 是指文件体积变小,但是像素数不变,长宽尺寸不变,那么质量可能下降. "缩" 是指文件的尺寸变小,也就是像素数减少,而长宽尺寸变小,文件体积同样会减小.    2.图片压的处理 对于"压"的功能,我们可以使用UIImageJPEGRepresentation或UIImagePNGRepresentation方法实现, 如代码: //图片压 - (void)_imageCompression{ UIImage