关于图片压缩,首先理解两个概念
1.“压” 是指 在不改变图片的尺寸,像素点的前提下,改变文件的体积变小,所以质量就丢失了. ->降低清晰度
2.“缩” 是指 改变了图片的尺寸,也就是像素点减少,文件的体积随之变小.
2.1关于PNG和JPEG格式”压”处理
UIImageJPEGRepresentation函数需要两个参数:图片的引用和压缩系数
UIImagePNGRepresentation只需要图片引用作为参数.
UIImagePNGRepresentation(UIImage *image)要比UIImageJPEGRepresentation(UIImage* image, 1.0)返回的图片数据量大很多.
同样的一张照片, 使用UIImagePNGRepresentation(image)返回的数据量大小为200K,而UIImageJPEGRepresentation(image, 1.0)返回的数据量大小只为150K,比前者少了50K.
如果对图片的清晰度要求不是极高,建议使用UIImageJPEGRepresentation,可以大幅度降低图片数据量.比如,刚才拍摄的图片,通过调用UIImageJPEGRepresentation(image, 1.0)读取数据时,返回的数据大小为140K,但更改压缩系数为0.5再读取数据时,返回的数据大小只有11K,大大压缩了图片的数据量,而且清晰度并没有相差多少,图片的质量并没有明显的降低。因此,在读取图片数据内容时,建议优先使用UIImageJPEGRepresentation,并可根据自己的实际使用场景,设置压缩系数,进一步降低图片数据量大小。
提示:压缩系数不宜太低,通常是0.3~0.7,过小则可能会出现黑边等。
3、图片“缩”处理
1.计算出原图的宽高比例 宽除以高
2.计算出imageView的宽高比例 宽除以高
3.比较两个比例
第一种算法
//如果原图的比例> view显示的比例大比例变成小比例
//第1步把图片裁剪成与view同比例的图片(以图片的高度为依据)
//裁剪的尺寸的x值= (图片的宽度-图片的高度*view的比例)/2 (除以2是为了得出x值,让截图从截取中间的值)
//裁剪成比例的图片
//第2步传入view的高度(以view的高度为依据)
//计算缩放的比例view的高度/图片的高度
//开启一个在原图片宽度乘以比例view高度的上下文把图片也画到同样的上下文中
//将图片也画到相同的框内
//如果原图的比例< view显示的比例小比例变成大比例
//第1步把图片裁剪成与view同比例的图片(以图片的宽度不变为依据)
//裁剪的尺寸的y值= (图片的高度- view的高度/view的宽度*图片的宽度)/2 (除以2是为了得出y值,让截图从截取中间的值)
//第2步按照传入view的宽度(以view的宽度为依据)
//计算缩放的比例view的宽度/图片的宽度
//开启一个在view的宽度图片的高度乘以比例的上下文把图片也画到同样的上下文中
//将图片也画到相同的框内
相关代码如下
//MARK:自动裁剪
public func autoClip(_ viewFrame:CGSize) -> UIImage?
{
//获取view的3倍的大小
let viewSize3x = CGSize(width: viewFrame.width*3, height: viewFrame.height*3)
//图片的宽除以图片的高度
let selfPercent = size.width/size.height
//view的宽除以view的高度
let viewPercent = viewSize3x.width/viewSize3x.height
//需要裁剪
if selfPercent > viewPercent
{
let outSide = (size.width - viewPercent*size.height)/2
if let clipImg = clip(CGRect(x: outSide, y: 0, width: size.width-outSide*2, height: size.height))
{
if let scanImg = clipImg.scaleToHeight(viewSize3x.height)
{
return scanImg
}
}
} else {
let outSide = (size.height - viewSize3x.height/viewSize3x.width*size.width)/2
if let clipImg = clip(CGRect(x: 0, y: outSide, width: size.width, height: size.height-outSide*2))
{
if let scanImg = clipImg.scaleToWidth(viewSize3x.width)
{
return scanImg
}
}
}
return nil
}
//MARK:根据宽和高较大的值缩放
public func scaleToMax(_ scalVal:CGFloat)->UIImage?
{
var scal:CGFloat=0
var isWidthBig=true
if size.height >= size.width
{
isWidthBig=false
}
if isWidthBig
{
scal=scalVal/size.width
}
else
{
scal=scalVal/size.height
}
UIGraphicsBeginImageContext(CGSize(width: size.width*scal, height: size.height*scal))
draw(in: CGRect(x: 0, y: 0, width: size.width*scal, height: size.height*scal))
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return result
}
//MARK:根据宽缩放
public func scaleToWidth(_ width:CGFloat)->UIImage?
{
var scal:CGFloat=0
scal=width/size.width
UIGraphicsBeginImageContext(CGSize(width: width, height: size.height*scal))
draw(in: CGRect(x: 0, y: 0, width: width, height: size.height*scal))
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return result
}
//MARK:根据高缩放
public func scaleToHeight(_ height:CGFloat)->UIImage?
{
var scal:CGFloat=0
scal=height/size.height
UIGraphicsBeginImageContext(CGSize(width: size.width*scal, height: height))
draw(in: CGRect(x: 0, y: 0, width: size.width*scal, height: height))
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return result
}
第二种算法
计算宽度比 view的宽度除以图片的宽度
计算高度比 view的高度除以图片的高度
如果宽度比大于高度比方的变成竖的
缩放比例按照宽度比计算
否则缩放比例按照高度比计算
缩放后的宽度就是 图片的宽度乘以缩放比
缩放后的高度就是 图片的高度乘以缩放比
如果宽度比大于高度比 方的变成竖的
改变开始画的y点 目标view的高度 - 缩放的高度 再除以2
如果宽度比小于高度比 方的变成横的
否则改变开始画的x点 = 目标view的宽度 - 缩放的宽度 再除以2
开启上下文 与目标的view一样大
创建一个rect 设置origin的起始点 和缩放的大小