關于圖片壓縮,首先理解兩個概念
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的起始點 ? 和縮放的大小