Swift AVFoundation QR code scanning and generation,
The project does not need to support iOS6 at last (tear collapse). Scanning the QR code can completely give up.ZXing
Library, instead of the systemAVFoundation
Now, takeswift
I wrote a Demo with the following effect:
Github address: click here
RelatedAVFoundation
AndCore Image
(Filter, etc.), you can first lookObjc. ioRelated introductions in sections 21st and 23rd.
Initialize video capture
// Initialize the video capture private func initCapture () {// represents the abstract hardware device. Here, the video let captureDevice = AVCaptureDevice. defaultDeviceWithMediaType (AVMediaTypeVideo) var error: NSError? // Input stream var captureInput = AVCaptureDeviceInput. deviceInputWithDevice (captureDevice, error: & error)? AVCaptureDeviceInput if (error! = Nil & captureInput = nil) {let errorAlert = UIAlertController (title: "Reminder", message: "Please go to the iPhone \" Settings-privacy-camera \ "option, allow XXX to access your camera ", preferredStyle :. alert) errorAlert. addAction (UIAlertAction (title: "OK", style: UIAlertActionStyle. default, handler: nil) self. presentViewController (errorAlert, animated: true, completion: nil)} bridge between else {// input and output, which coordinates data transmission from intput to output. (See the meaning of the word, session-session) captureSes Sion = AVCaptureSession () captureSession !. AddInput (captureInput) // output stream let captureMetadataOutput = AVCaptureMetadataOutput () // restricted scan area http://blog.csdn.net/lc_obj/article/details/41549469 captureMetadataOutput. rectOfInterest = CGRectMake (128.0/ScreenWH. screenHeight, (ScreenWH. screenWidth-280.0)/ScreenWH. screenWidth * 2.0, 280.0/ScreenWH. screenHeight, 280.0/ScreenWH. screenWidth) captureSession !. AddOutput (captureMetadataOutput) // The added queue must be a serial captureMetadataOutput. setMetadataObjectsDelegate (self, queue: dispatch_get_main_queue () // specify the information type, QRCode, you know captureMetadataOutput. metadataObjectTypes = [AVMetadataObjectTypeQRCode] // use this preview layer and image information capture session to display the video videoPreviewLayer = AVCaptureVideoPreviewLayer (session: captureSession !) VideoPreviewLayer !. VideoGravity = AVLayerVideoGravityResizeAspectFill videoPreviewLayer !. Frame = view. bounds view. layer. addSublayer (videoPreviewLayer !) }}
PS: LZ used to scan Sina Weibo and found that the scan box was dumb, that is, you didn't point it at the QR code, as long as the QR code entered the mobile phone camera range, it can be decoded successfully .... Bytes
Therefore, LZ imposes a scan area restriction in the Code (it feels boring)
Implement proxy Decoding
// MARK:-AVCaptureMetadataOutputObjectsDelegate func captureOutput (captureOutput: AVCaptureOutput !, DidOutputMetadataObjects metadataObjects: [AnyObject]!, FromConnection connection: AVCaptureConnection !) {If metadataObjects = nil | metadataObjects. count = 0 {captureView !. Frame = CGRectZero return} // The retrieved data for metadataObject in metadataObjects {if metadataObject. type = AVMetadataObjectTypeQRCode {let metadata = metadataObject! AVMetadataMachineReadableCodeObject // The metadata object is converted into the coordinate of the layer. let codeCoord = videoPreviewLayer !. TransformedMetadataObjectForMetadataObject (metadata)! AVMetadataMachineReadableCodeObject captureView !. Frame = codeCoord. bounds if metadata. stringValue! = Nil {println ("\ (metadata. stringValue)") self. captureSession !. StopRunning () let successAlert = UIAlertController (title: "prompt", message: "Open" + metadata. stringValue, preferredStyle :. alert) successAlert. addAction (UIAlertAction (title: "cancel", style :. default, handler: {(_)-> Void in self. stopCapture ()}) successAlert. addAction (UIAlertAction (title: "OK", style :. default, handler: {(_)-> Void in if metadata. stringValue. lowercaseString. hasPrefix ("http") {UIApplic Ation. sharedApplication (). openURL (NSURL (string: metadata. stringValue )!) Self. navigationController !. PopViewControllerAnimated (true)}) self. presentViewController (successAlert, animated: true, completion: nil )}}}}
Data ConversionAVMetadataMachineReadableCodeObject
Corresponding QR code.
Generate QR code
// MARK:-Private Methods private func createQRForString (qrString: String ?, QrImageName: String ?) -> UIImage? {If let sureQRString = qrString {let stringData = sureQRString. dataUsingEncoding (NSUTF8StringEncoding, allowLossyConversion: false) // create a QR code filter let qrFilter = CIFilter (name: "CIQRCodeGenerator") qrFilter. setValue (stringData, forKey: "inputMessage") qrFilter. setValue ("H", forKey: "inputCorrectionLevel") let qrCIImage = qrFilter. outputImage // create a color filter, black and white let colorFilter = CIFilter (name: "CIFals EColor ") colorFilter. setDefaults () colorFilter. setValue (qrCIImage, forKey: "inputImage") colorFilter. setValue (CIColor (red: 0, green: 0, blue: 0), forKey: "inputColor0") colorFilter. setValue (CIColor (red: 1, green: 1, blue: 1), forKey: "inputColor1") // return the QR code image let codeImage = UIImage (CIImage: colorFilter. outputImage. imageByApplyingTransform (CGAffineTransformMakeScale (5, 5) // generally, the QR code is customized and placed in the middle If let iconImage = UIImage (named: qrImageName !) {Let rect = CGRectMake (0, 0, codeImage !. Size. width, codeImage !. Size. height) UIGraphicsBeginImageContext (rect. size) codeImage !. DrawInRect (rect) let avatarSize = CGSizeMake (rect. size. width * 0.25, rect. size. height * 0.25) let x = (rect. width-avatarSize. width) * 0.5 let y = (rect. height-avatarSize. height) * 0.5 iconImage. drawInRect (CGRectMake (x, y, avatarSize. width, avatarSize. height) let resultImage = UIGraphicsGetImageFromCurrentImageContext () UIGraphicsEndImageContext () return resultImage} return codeImage} return nil}
End:AVFoundation
This framework is especially powerful. It can also be used to write Custom cameras, take photos, and record videos.