前言
周末在微博上看到@周楷雯Kevin說起CALayer抗鋸齒的問題
具體做法是:
layer.allowsEdgeAntialiasing = true
想起了很久以前也遇到過類似的問題 那時候要做一個類貼紙的應用 理所當然會遇到貼紙縮放和旋轉的問題 所以鋸齒的問題也是需要解決的 但是那時候是iOS4,5的時代 壓根沒有上面說的allowsEdgeAntialiasing這個東西(這個東西iOS7才公開 不過iOS6據說也可以用 但是黑科技嘛..你懂的)
所以當時求助了萬能的stackoverflow 得到了一個非常簡約而不簡單的方法 就是我在微博上說的 只要把需要顯示的圖片留一個像素的透明邊 就搞定了
方法
方法比較簡單 我寫成了一個UIImage的Category方法 然後一直塵封在我的工具庫中好幾年(遇到這個問題我才想起來)
- (UIImage *)antiAlias { CGFloat border = 1.0f; CGRect rect = CGRectMake(border, border, self.size.width-2*border, self.size.height-2*border); UIImage *img = nil; UIGraphicsBeginImageContext(CGSizeMake(rect.size.width,rect.size.height)); [self drawInRect:CGRectMake(-1, -1, self.size.width, self.size.height)]; img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); UIGraphicsBeginImageContext(self.size); [img drawInRect:rect]; UIImage* antiImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return antiImage; }
先來看看實際的效果
可以看到旋轉的時候若不做任何處理 確實是會有明顯的鋸齒 而使用透明邊的方法 或者設置allowsEdgeAntialiasing 都可以消除鋸齒
接下來看看這兩種方法的性能比較 測試方法是在我的iPhone 5S上接連對500個UIImageView進行旋轉 對比幀數 其結果如下
結果表明 allowsEdgeAntialiasing的性能還是比透明邊的方式要差一點 所以…
如果你的應用要支持iOS6- 可以參考透明邊的方法 唯一的缺點是顯示出來會比原來小那麼一點點(我的做法是直接cut掉1px的邊 當然你也可以直接在圖像外面加1px的透明邊)
如果你的應用僅支持iOS7 推薦使用allowsEdgeAntialiasing來設置 簡單方便咯 如果性能上覺得吃力的話 可以再考慮透明邊的方法
小結
文中的demo可以在這裡找到
測試的方法也許不太嚴謹(也是臨時起意寫的這篇 所以並沒有花太多時間) 如果有錯誤 請大家提出來