Is there a way to generate QR code image on iOS
38,680
Solution 1
Since iOS 7, you can use a Core Image filter to generate QR images. See the final tip here:
- (CIImage *)createQRForString:(NSString *)qrString {
NSData *stringData = [qrString dataUsingEncoding: NSISOLatin1StringEncoding];
CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[qrFilter setValue:stringData forKey:@"inputMessage"];
return qrFilter.outputImage;
}
Solution 2
For Obj-C version that perfectly works for me, I've mixed answers पवन and Teja Kumar Bethina:
NSString *qrString = @"My string to encode";
NSData *stringData = [qrString dataUsingEncoding: NSUTF8StringEncoding];
CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[qrFilter setValue:stringData forKey:@"inputMessage"];
[qrFilter setValue:@"H" forKey:@"inputCorrectionLevel"];
CIImage *qrImage = qrFilter.outputImage;
float scaleX = self.qrImageView.frame.size.width / qrImage.extent.size.width;
float scaleY = self.qrImageView.frame.size.height / qrImage.extent.size.height;
qrImage = [qrImage imageByApplyingTransform:CGAffineTransformMakeScale(scaleX, scaleY)];
self.qrImageView.image = [UIImage imageWithCIImage:qrImage
scale:[UIScreen mainScreen].scale
orientation:UIImageOrientationUp];
Solution 3
Using Swift 2
import UIKit
import CoreImage
func createQRFromString(str: String) -> CIImage? {
let stringData = str.dataUsingEncoding(NSUTF8StringEncoding)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter?.setValue(stringData, forKey: "inputMessage")
filter?.setValue("H", forKey: "inputCorrectionLevel")
return filter?.outputImage
}
if let img = createQRFromString("Hello world program created by someone") {
let somImage = UIImage(CIImage: img, scale: 1.0, orientation: UIImageOrientation.Down)
}
Swift 3.0
import UIKit
import CoreImage
func createQRFromString(_ str: String) -> CIImage? {
let stringData = str.data(using: String.Encoding.utf8)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter?.setValue(stringData, forKey: "inputMessage")
filter?.setValue("H", forKey: "inputCorrectionLevel")
if let img = createQRFromString("Hello world program created by someone") {
let somImage = UIImage(ciImage: img, scale: 1.0, orientation: UIImageOrientation.down)
}
return filter?.outputImage
}
if let img = createQRFromString("Hello world program created by someone") {
let somImage = UIImage(ciImage: img, scale: 1.0, orientation: UIImageOrientation.down)
}
Swift 4.2
private func createQRFromString(str: String) -> CIImage? {
let stringData = str.data(using: .utf8)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter?.setValue(stringData, forKey: "inputMessage")
filter?.setValue("H", forKey: "inputCorrectionLevel")
return filter?.outputImage
}
var qrCode: UIImage? {
if let img = createQRFromString(str: "Hello world program created by someone") {
let someImage = UIImage(
ciImage: img,
scale: 1.0,
orientation: UIImage.Orientation.down
)
return someImage
}
return nil
}
Xcode 12.4 or Swift version >= 5.2
import UIKit
import CoreImage
func createQRFromString(str: String) -> CIImage? {
let stringData = str.data(using: .utf8)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter?.setValue(stringData, forKey: "inputMessage")
filter?.setValue("H", forKey: "inputCorrectionLevel")
return filter?.outputImage
}
if let img = createQRFromString(str: "Hello world program created by someone") {
let somImage = UIImage(ciImage: img, scale: 1.0, orientation: .down)
}
Solution 4
It has been a while since this question was asked and a number of almost perfect answers have been given already. However I had to tweak and combine several answers to get it working perfectly for AppleTV 4K, iPhone X and iPadPro using Xcode 9.2 in 2018. Here's the code if anyone needs it.
@IBOutlet weak var qrCodeBox: UIImageView!
func createQRFromString(_ str: String, size: CGSize) -> UIImage {
let stringData = str.data(using: .utf8)
let qrFilter = CIFilter(name: "CIQRCodeGenerator")!
qrFilter.setValue(stringData, forKey: "inputMessage")
qrFilter.setValue("H", forKey: "inputCorrectionLevel")
let minimalQRimage = qrFilter.outputImage!
// NOTE that a QR code is always square, so minimalQRimage..width === .height
let minimalSideLength = minimalQRimage.extent.width
let smallestOutputExtent = (size.width < size.height) ? size.width : size.height
let scaleFactor = smallestOutputExtent / minimalSideLength
let scaledImage = minimalQRimage.transformed(
by: CGAffineTransform(scaleX: scaleFactor, y: scaleFactor))
return UIImage(ciImage: scaledImage,
scale: UIScreen.main.scale,
orientation: .up)
}
override func viewDidLoad() {
super.viewDidLoad()
let myQRimage = createQRFromString("https://www.apple.com",
size: qrCodeBox.frame.size)
qrCodeBox.image = myQRimage
}
Solution 5
Code to generate QR image in Swift 2.0.
let reqStr = “string to convert as QR code”
let data = reqStr.dataUsingEncoding(NSISOLatin1StringEncoding, allowLossyConversion: false)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter!.setValue(data, forKey: "inputMessage")
let qrImage:CIImage = filter!.outputImage!
//qrImageView is a IBOutlet of UIImageView
let scaleX = qrImageView.frame.size.width / qrImage.extent.size.width
let scaleY = qrImageView.frame.size.height / qrImage.extent.size.height
let resultQrImage = qrImage.imageByApplyingTransform(CGAffineTransformMakeScale(scaleX, scaleY))
qrImageView.image = UIImage(CIImage: resultQrImage)
Author by
user1561181
Updated on April 09, 2021Comments
-
user1561181 about 3 years
Is there a standard way to generate a QR code and attach it to a mail item from iOS client app (no server code)?
-
Royston Yinkore about 10 yearsThe image is blurry. How do i fix?
-
quarac about 10 yearsLook in the link for the function: createNonInterpolatedUIImageFromCIImage
-
T Blank over 9 yearsYou should be using
NSISOLatin1StringEncoding
rather than UTF-8 according to the docs. -
quarac over 9 yearsThanks Travis, answer updated with NSISOLatin1StringEncoding, docs are in developer.apple.com/library/mac/documentation/GraphicsImaging/…
-
kevinl about 9 yearsif the qr code is blurry, try this. CIImage *image = [self createQRForString:qrString]; CGAffineTransform transform = CGAffineTransformMakeScale(5.0f, 5.0f); // Scale by 5 times along both dimensions CIImage *output = [image imageByApplyingTransform: transform];
-
vichhai over 8 years@kevinl: your code work fine on the simulator. But for the real devices it's still blur. What should I do to make it clear?
-
NSDeveloper over 8 yearsZXing is a choice for generate QRCode and this is a good answer.
-
Yogendra Patel about 7 yearsYou are sure to ZXing libarary avaliable for QR Code in iOS? @Avivo
-
jpat827 almost 7 yearsZXingObjC is an Objective C implementation of ZXing. It should be usable with Swift by using a bridging header file.
-
haxpor over 6 yearsI use kevin's solution to make image not blur, it works on real device.
-
Ben Baron over 5 yearsThere's actually a small bug here. You have to multiply
scaledImage
byUIScreen.main.scale
or the final UIImage will be too small. For example on an iPhone X with screen scale of 3.0, if you try and make a 300x300 QR code the final UIImage will be 100x100 if you use this code as-is. -
Albert Renshaw over 4 years@kevinl To add on to what Kevin has said, you can also apply, to any imageView that may be scaling arbitrarily (like a scrollview zoom), a nearest neighbor interpolation since all visual data in a QR Code is orthogonal, this will cause sharp/crisp edges when scaling, set the .layer.minificationFilter and .layer.magnificationLayer to
kCAFilterNearest
-
Albert Renshaw about 4 yearsNote: Make Sure you convert the CIImage to a UIImage using CGContext, if you just use
UIImage imageWithCIImage:
you will get a bmp formatted image which causescontentMode
to fail on certain architectures. For example, on my iPhone-11 (arm64) aspectFit worked with the UIImage from CIImage but on my iPhone-X (armv7s) it failed and fell back to scaleToFill (which makes QR codes not work). Detailed Explanation here: stackoverflow.com/a/15886422/2057171 -
Kilian almost 3 years@AlbertRenshaw Thank you! Without doing that I wasn't able to see any image at all inside of a SwiftUI view.