歡迎訪問我的個人主頁獲取本文示例代碼
前言
工作中有一個需求,將服務端已經生成好的黑白二維碼變成漸變的二維碼,具體效果如下。
本文將介紹如何使用CALayer的Mask實現漸變二維碼的效果。下面是我們需要處理的二維碼圖片。
原理
蘋果對CALayer的Mask(遮罩)是這樣描述的,被遮罩的Layer位於Mask不透明的部分才會被顯示。所以我們的基本思路是讓二維碼白色的部分變的完全透明,黑色的部分不透明,然後把處理後的圖作為一個漸變Layer的Mask。這樣黑色部分將會顯示漸變Layer上對應的部分,白色部分將顯示漸變Layer後面Layer的顏色。
處理原始二維碼圖片
我們將原始二維碼圖片轉化成遮罩需要的圖片。首先我們把圖片數據抽取出來,格式化為ARGB格式的像素數據。具體做法就是生成一個ARGB空間的CGContext,將原始二維碼圖片繪制上去。然後像素數據就會在imageData中了。
let bitsPerComponent = 8 let bytesPerPixel = 4 let width:Int = Int(image.size.width) let height:Int = Int(image.size.height) let imageData = UnsafeMutableRawPointer.allocate(bytes: Int(width * height * bytesPerPixel), alignedTo: 8) // 將原始黑白二維碼圖片繪制到像素格式為ARGB的圖片上,繪制後的像素數據在imageData中。 let colorSpace = CGColorSpaceCreateDeviceRGB() let imageContext = CGContext.init(data: imageData, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: bitsPerComponent, bytesPerRow: width * bytesPerPixel, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue ) UIGraphicsPushContext(imageContext!) imageContext?.translateBy(x: 0, y: CGFloat(height)) imageContext?.scaleBy(x: 1, y: -1) image.draw(in: CGRect.init(x: 0, y: 0, width: width, height: height)) UIGraphicsPopContext()
接下來我們將二維碼白色的部分變的完全透明,黑色的部分不透明。我們遍歷所有像素,根據像素的Red值,設置像素的Alpha值。如果R大於100,我們認為是白色,所以將Alpha設為0,全透明。如果R小於100,我們認為是黑色,所以將Alpha設為255,不透明。
// 根據每個像素R通道的值修改Alpha通道的值,當Red大於100,則將Alpha置為0,反之置為255 for row in 0..設置遮罩
最後我們創建漸變Layer,然後把處理後的二維碼圖片作為遮罩設置給漸變Layer。
lazy var gradientLayer: CAGradientLayer = { let layer = CAGradientLayer.init() layer.colors = [UIColor.red.cgColor, UIColor.orange.cgColor, UIColor.cyan.cgColor] self.layer.addSublayer(layer) layer.frame = self.bounds return layer }() // 設置黑白二維碼圖片 func setQRCodeImage(qrcodeImage: UIImage) { let imageMask = genQRCodeImageMask(grayScaleQRCodeImage: qrcodeImage) maskLayer.contents = imageMask maskLayer.frame = self.bounds self.gradientLayer.mask = maskLayer }總結
我們主要利用CALayer的遮罩特性完成了漸變二維碼的效果。涉及到CoreGraphics和UIKit等相關知識。當然我們還有其他方式實現這一效果,比如OpenGL ES或者Metal,我將在另一篇文章中介紹如何使用Metal實現漸變二維碼的效果。
作者:handyTOOL
鏈接:http://www.jianshu.com/p/709329d9fb81
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。