tesmojones
tesmojones

Reputation: 2667

QR Code reader & generator in Swift

Currently in Objective-C, i use Zbar(http://zbar.sourceforge.net/) to generate & read QR Code. Now, i want to move on Swift development only, is there any 'how to' or library about generate and read QR Code in Swift ?

Upvotes: 8

Views: 14429

Answers (6)

jazzbpn
jazzbpn

Reputation: 7368

SWIFT 3: QR Code Reader

STEP FIRST: Simply add a row in info.plist and type Privacy - CameraUsageDescription into the newly created row and add a string meant for informing the user on why access to the camera is needed within your app.

STEP SECOND: Use this code in your ViewController class

class QrCodeScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {

var calssName:String = "QrCodeScannerViewController"

var captureSession:AVCaptureSession?
var videoPreviewLayer:AVCaptureVideoPreviewLayer?
var qrCodeFrameView:UIView?

@IBOutlet weak var messageLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    captureQRCode()

}


/* Open camera to capture QR CODE */
func captureQRCode() {
    captureSession = AVCaptureSession()
    let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

    let input = try! AVCaptureDeviceInput(device: device) as AVCaptureDeviceInput
    captureSession?.addInput(input)

    let output = AVCaptureMetadataOutput()
    output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
    captureSession?.addOutput(output)
    output.metadataObjectTypes = [AVMetadataObjectTypeQRCode]

    videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    let bounds = self.view.layer.bounds
    videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
    videoPreviewLayer?.bounds = bounds
    videoPreviewLayer?.position = CGPoint(x:bounds.midX, y:bounds.midY)

    self.view.layer.addSublayer(videoPreviewLayer!)
    captureSession?.startRunning()
}


/* onAtivityResult from App Delegate */
func captureOutput(_ captureOutput: AVCaptureOutput!,
                   didOutputMetadataObjects metadataObjects: [Any]!,
                   from connection: AVCaptureConnection!) {
    for item in metadataObjects {
        if let metadataObject = item as? AVMetadataMachineReadableCodeObject {
            if metadataObject.type == AVMetadataObjectTypeQRCode {

                print("QR Code: \(metadataObject.stringValue)")
                hideCamera(voucherHashkey: metadataObject.stringValue)

            }
        }
    }

}


/* Hide camera after getting result */
func hideCamera(voucherHashkey:String){

    self.captureSession?.stopRunning()
    self.videoPreviewLayer?.removeFromSuperlayer()
    self.videoPreviewLayer = nil;
    self.captureSession = nil;

    // sendVocherDataToServer(voucherHashKey: voucherHashkey)

}
}

Upvotes: 1

shikha kochar
shikha kochar

Reputation: 163

QR Code Generator in Swift :

in viewDidLoad :

var qrcodeImage: CIImage!    
@IBOutlet var qrtext: UITextField!
@IBOutlet var imgQRCode: UIImageView!
@IBAction func displayQRcode(sender: AnyObject) {
  if qrcodeImage == nil {
    if qrtext.text == "" {
      return
    }

    let data = qrtext.text!.dataUsingEncoding(NSISOLatin1StringEncoding, allowLossyConversion: false)

    let filter = CIFilter(name: "CIQRCodeGenerator")
    filter!.setValue(data, forKey: "inputMessage")
    filter!.setValue("Q", forKey: "inputCorrectionLevel")
    qrcodeImage = filter!.outputImage
    qrtext.resignFirstResponder()
    displayQRCodeImage()
  }
  else {
    self.imgQRCode.image = nil
    self.qrcodeImage = nil
  }
}

func displayQRCodeImage() {
  let scaleX = imgQRCode.frame.size.width / qrcodeImage.extent.size.width
  let scaleY = imgQRCode.frame.size.height / qrcodeImage.extent.size.height
  let transformedImage = qrcodeImage.imageByApplyingTransform(CGAffineTransformMakeScale(scaleX, scaleY))
  imgQRCode.image = UIImage(CIImage: transformedImage)
}

And For QRCode Reader

please check this Tutorial http://www.appcoda.com/qr-code-reader-swift/

Upvotes: 2

kui liu
kui liu

Reputation: 132

Here is the code I wrote to generate QRcode in objective-C:

#pragma mark - qrimage

-(UIImage *)generateQRimg:(NSString *)a withsize:(CGFloat)b
{

    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];

    [filter setDefaults];

    NSData *data = [a dataUsingEncoding:NSUTF8StringEncoding];
    [filter setValue:data forKey:@"inputMessage"];

    CIImage *outputImage = [filter outputImage];

    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgImage = [context createCGImage:outputImage
                                       fromRect:[outputImage extent]];

    UIImage *image = [UIImage imageWithCGImage:cgImage
                                         scale:1.
                                   orientation:UIImageOrientationUp];

    // Resize without interpolating
    UIImage *resized = [self resizeImage:image
                             withQuality:kCGInterpolationNone
                                    rate:b];

    CGImageRelease(cgImage);
    return resized;
}


- (UIImage *)resizeImage:(UIImage *)image withQuality  (CGInterpolationQuality)quality rate:(CGFloat)rate

{

    UIImage *resized = nil;
    CGFloat width = image.size.width * rate;
    CGFloat height = image.size.height * rate;

    UIGraphicsBeginImageContext(CGSizeMake(width, height));
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetInterpolationQuality(context, quality);
    [image drawInRect:CGRectMake(0, 0, width, height)];
    resized = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resized;
}

Upvotes: 1

Daniel Maclean
Daniel Maclean

Reputation: 789

This GitHub project provides some code on how to generate a QR code:

https://github.com/aschuch/QRCode

// NSData
let data = "http://schuch.me".dataUsingEncoding(NSISOLatin1StringEncoding)
let qrCode = QRCode(data)
qrCode.image

As for reading, there is another good GitHub project here:

https://github.com/yannickl/QRCodeReader.swift

// Good practice: create the reader lazily to avoid cpu overload during the
// initialization and each time we need to scan a QRCode
lazy var reader = QRCodeReaderViewController(metadataObjectTypes: [AVMetadataObjectTypeQRCode])

@IBAction func scanAction(sender: AnyObject) {
  // Retrieve the QRCode content
  // By using the delegate pattern
  reader.delegate = self

  // Or by using the closure pattern
  reader.completionBlock = { (result: String?) in
    println(result)
  }

  // Presents the reader as modal form sheet
  reader.modalPresentationStyle = .FormSheet
  presentViewController(reader, animated: true, completion: nil)
}

// MARK: - QRCodeReader Delegate Methods

func reader(reader: QRCodeReader, didScanResult result: String) {
  self.dismissViewControllerAnimated(true, completion: nil)
}

func readerDidCancel(reader: QRCodeReader) {
  self.dismissViewControllerAnimated(true, completion: nil)
}

I suggest you check out these two projects and combine the code to make your desired behaviour.

Upvotes: 2

kui liu
kui liu

Reputation: 132

here is the code i wrote to generate QRcode in swift.

//MARK:- generate QR code
func generateQRImage(stringQR:NSString, withSizeRate rate:CGFloat) -> UIImage
{
    var filter:CIFilter = CIFilter(name:"CIQRCodeGenerator")
    filter.setDefaults()

    var data:NSData = stringQR.dataUsingEncoding(NSUTF8StringEncoding)!
    filter.setValue(data, forKey: "inputMessage")

    var outputImg:CIImage = filter.outputImage

    var context:CIContext = CIContext(options: nil)
    var cgimg:CGImageRef = context.createCGImage(outputImg, fromRect: outputImg.extent())

    var img:UIImage = UIImage(CGImage: cgimg, scale: 1.0, orientation: UIImageOrientation.Up)!

    var width  = img.size.width * rate
    var height = img.size.height * rate

    UIGraphicsBeginImageContext(CGSizeMake(width, height))
    var cgContxt:CGContextRef = UIGraphicsGetCurrentContext()
    CGContextSetInterpolationQuality(cgContxt, kCGInterpolationNone)
    img.drawInRect(CGRectMake(0, 0, width, height))
    img = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return img
}

Upvotes: 8

Ron Fessler
Ron Fessler

Reputation: 2789

Beginning with iOS 7, iOS devices can read QR codes. However, there is no built-in way to generate a QR code. Here's a quick and dirty QR code reader.

First, import AVFoundation and add AVCaptureMetadataOutputObjectsDelegate

Next, setup the capture session:

func captureQRCode() {
    let session = AVCaptureSession()
    let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)

    let input = AVCaptureDeviceInput.deviceInputWithDevice(device, error: nil) as AVCaptureDeviceInput
    session.addInput(input)

    let output = AVCaptureMetadataOutput()
    output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
    session.addOutput(output)
    output.metadataObjectTypes = [AVMetadataObjectTypeQRCode]

    let previewLayer = AVCaptureVideoPreviewLayer(session: session)
    let bounds = self.view.layer.bounds
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
    previewLayer.bounds = bounds
    previewLayer.position = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds))

    self.view.layer.addSublayer(previewLayer)
    session.startRunning()
}

Finally, handle the delegate

func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
    for item in metadataObjects {
        if let metadataObject = item as? AVMetadataMachineReadableCodeObject {
            if metadataObject.type == AVMetadataObjectTypeQRCode {
                println("QR Code: \(metadataObject.stringValue)")
            }
        }
    }
}

Upvotes: 7

Related Questions