Swiftui: UIimage (Qrcode) Does Not Load After Calling Function

SwiftUI: UIImage (QRCode) does not load after calling function

This seems to do the trick:

func generateQRCode(from string: String) -> UIImage? {

let data = string.data(using: String.Encoding.ascii)
var uiImage: UIImage?
if let filter = CIFilter(name: "CIQRCodeGenerator",
parameters: ["inputMessage": data,
"inputCorrectionLevel": "L"]) {

if let outputImage = filter.outputImage,
let cgImage = CIContext().createCGImage(outputImage,
from: outputImage.extent) {
let size = CGSize(width: outputImage.extent.width * 3.0,
height: outputImage.extent.height * 3.0)
UIGraphicsBeginImageContext(size)
if let context = UIGraphicsGetCurrentContext() {
context.interpolationQuality = .none
context.draw(cgImage,
in: CGRect(origin: .zero,
size: size))
uiImage = UIGraphicsGetImageFromCurrentImageContext()
}
UIGraphicsEndImageContext()
}
}
return uiImage
}

Generating QR Code with SwiftUI shows empty picture

I guess the problem is that your CIImage is not actually "produced". You see, a CIImage is just a recipe for an image that needs to be rendered by a CIContext into an actual bitmap image.

The (poorly documented) convenient initializer UIImage(ciImage:) only works if the destination you assign the image to understands that the pixels of the UIImage are not yet there and need to be rendered first. UIImageView could handle this, but it seems SwiftUI's Image doesn't.

What you need to do is to create a CIContext (once, maybe as a property of your view) and use it to render your barcode image into a bitmap like this:

let cgImage = self.ciContext.createCGImage(scaledQrImage, from: scaledQrImage.extent)
self.image = Image(uiImage: UIImage(cgImage: cgImage))

imageView.image = UIImage(ciImage: ) won't update a second time

Quick searching ... seems to be either a "bug" or a change...

Changing your generator code to this seems to correct the issue:

func generateQRCode(from string: String) -> UIImage? {
let data = string.data(using: String.Encoding.ascii)

let context = CIContext()

if let filter = CIFilter(name: "CIQRCodeGenerator") {
filter.setValue(data, forKey: "inputMessage")
let transform = CGAffineTransform(scaleX: 3, y: 3)

if let output = filter.outputImage?.transformed(by: transform) {
if let retImg = context.createCGImage(output, from: output.extent) {
return UIImage(cgImage: retImg)
}
}
}
return nil
}

func generateBarcode(from string: String) -> UIImage? {
let data = string.data(using: String.Encoding.ascii)

let context = CIContext()

if let filter = CIFilter(name: "CICode128BarcodeGenerator") {
filter.setValue(data, forKey: "inputMessage")
let transform = CGAffineTransform(scaleX: 3, y: 3)

if let output = filter.outputImage?.transformed(by: transform) {
if let retImg = context.createCGImage(output, from: output.extent) {
return UIImage(cgImage: retImg)
}
}
}
return nil
}

overlay image in the middle of qr code ios

Try something like this, which will center it inside the view.

The important lines of code to center the UIImageView is as follows:

overlayImageView.translatesAutoresizingMaskIntoConstraints = false
overlayImageView.contentMode = .center

qrCodeImageView.addSubview(overlayImageView)

let centerXConst = NSLayoutConstraint(item: overlayImageView, attribute: .centerX, relatedBy: .equal, toItem: qrCodeImageView, attribute: .centerX, multiplier: 1, constant: 0)
let centerYConst = NSLayoutConstraint(item: overlayImageView, attribute: .centerY, relatedBy: .equal, toItem: qrCodeImageView, attribute: .centerY, multiplier: 1, constant: 0)
NSLayoutConstraint.activate([centerXConst, centerYConst])

I use this exact code to center an icon on the QR Code:

class ViewController: UIViewController {

@IBOutlet weak var qrCodeImageView: UIImageView!
var qrCodeImage: CIImage!

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.

let textField = "fooqarcode"
let data = textField.data(using: String.Encoding.isoLatin1, allowLossyConversion: false)

let filter = CIFilter(name: "CIQRCodeGenerator")

filter?.setValue(data, forKey: "inputMessage")
filter?.setValue("Q", forKey: "inputCorrectionLevel")

qrCodeImage = (filter?.outputImage)!

let scaleX = qrCodeImageView.frame.size.width / qrCodeImage.extent.size.width
let scaleY = qrCodeImageView.frame.size.height / qrCodeImage.extent.size.height

let transformedImage = qrCodeImage.transformed(by: CGAffineTransform(scaleX: scaleX, y: scaleY))
qrCodeImageView.image = UIImage(ciImage: transformedImage)

let overlayImageView = UIImageView(image: UIImage(named: "block.png"))
overlayImageView.translatesAutoresizingMaskIntoConstraints = false
overlayImageView.contentMode = .center

qrCodeImageView.addSubview(overlayImageView)

let centerXConst = NSLayoutConstraint(item: overlayImageView, attribute: .centerX, relatedBy: .equal, toItem: qrCodeImageView, attribute: .centerX, multiplier: 1, constant: 0)
let centerYConst = NSLayoutConstraint(item: overlayImageView, attribute: .centerY, relatedBy: .equal, toItem: qrCodeImageView, attribute: .centerY, multiplier: 1, constant: 0)
NSLayoutConstraint.activate([centerXConst, centerYConst])
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Sample Image

Sample Image

Why does putting an SF symbol in a UIImage and then in a SwiftUI Image View result in a blurry image?

When you use Image(systemName:) the system draws to the screen using vector graphics, resulting in sharp, un-blurry renderings.

However, UIImage, including, it seems UIImage(systemName:) is a bitmapped image, at a set resolution. If you scale it up (as you're doing in your second block of code), you'll get blurriness, because you're not getting the benefits of the vector graphics.

Using a pattern like the following would allow you to conditionally display a Image(uiImage:) or Image(systemName:) and still use the same set of modifiers for each:

struct ContentView: View {
@State var displayedImage : UIImage?

var imageToDisplay: Image {
if let displayedImage = displayedImage {
return Image(uiImage: displayedImage)
} else {
return Image(systemName: "camera.circle")
}
}

var body: some View {
imageToDisplay
.resizable()
.scaledToFill()
.aspectRatio(contentMode: .fit)
.frame(width: 400, height: 400)
}
}

iOS 7 Core Image QR Code generation too blur

I was about to start bounty on this question but i found the answer.

What you need is a scale filter. To achieve this with CoreImage, you need to do something like this:

CIImage *input = [CIImage imageWithCGImage: ImageView.Image.CGImage]; // input image is 100 X 100
CGAffineTransform transform = CGAffineTransformMakeScale(5.0f, 5.0f); // Scale by 5 times along both dimensions
CIImage *output = [input imageByApplyingTransform: transform];
// output image is now 500 X 500

FROM THIS SO ANSWER: https://stackoverflow.com/a/16316701/2859764



Related Topics



Leave a reply



Submit