Value of type UIImage has no member cgImageOrientation - swift

I am new coreml and I was reading a book I came across a code snippet and when I tried to run it I got the above error , I Googled but got no luck ,
here is my code
import UIKit
import Vision
extension UIImage {
func detectFaces(completion:#escaping ([VNFaceObservation]?)->()){
guard let image = self.cgImage else {
completion(nil)
return
}
let request = VNDetectFaceRectanglesRequest()
DispatchQueue.global().async {
let handler = VNImageRequestHandler(cgImage: image, orientation: self.cgImageOrientation)
//above error here I think cgImageOrientation is no longer available but what's the solution anyways
}
}
}
here I am using swiftUI and lifecycle methods are also selected as swiftui
,
The book name is "Practical Artificial intelligence with swift" by orielly

You need to continue working through the tutorial before you'll be able to compile it. The next section of the book talks about creating Views.swift, and step 8 of that section includes this extension:
extension UIImage {
func fixOrientation() -> UIImage? {
UIGraphicsBeginImageContext(self.size)
self.draw(at: .zero)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
var cgImageOrientation: CGImagePropertyOrientation {
switch self.imageOrientation {
case .up: return .up
case .down: return .down
case .left: return .left
case .right: return .right
case .upMirrored: return .upMirrored
case .downMirrored: return .downMirrored
case .leftMirrored: return .leftMirrored
case .rightMirrored: return .rightMirrored
}
}
}

Related

Is there a better way to do this switch?

What I'm trying to do is: that based on the notification type, I'll change the image of the tableViewCell, and I know that maybe there is a better way of achieving this. I thought that maybe using enums would be a good way, but there is a lot of code in here, and it will do nothing but grow with time.
Is there a better way of achieving this?
enum NotificationIcons {
case newPayment
case newPaymentMethod
case newOffers
case userInfoUpdate
case supportChat
case newAnnouncement
case cardVerification
var strings: String {
switch self {
case .newPayment:
return "new_payment"
case .newPaymentMethod:
return "new_payment_method"
case .newOffers:
return "new_offers"
case .userInfoUpdate:
return "user_info_update"
case .supportChat:
return "support_chat"
case .newAnnouncement:
return "new_announcement"
case .cardVerification:
return "card_verification"
}
}
var image: UIImage {
switch self {
case .newPayment: return UIImage(named: "Icon-notification-service-pay")!
case .newPaymentMethod: return UIImage(named: "Icon-notification-add-paycard")!
case .newOffers: return UIImage(named: "Icon-notification-promos")!
case .userInfoUpdate: return UIImage(named: "Icon-notification-update-data")!
case .supportChat: return UIImage(named: "Icon-notification-support")!
case .newAnnouncement: return UIImage(named: "Icon-notification-advice")!
case .cardVerification: return UIImage(named: "Icon-notification-add-paycard")!
}
}
var detailImage: UIImage {
switch self {
case .newPayment: return UIImage(named: "Icon-notification-detail-service-pay")!
case .newPaymentMethod: return UIImage(named: "Icon-notification-detail-add-paycard")!
case .newOffers: return UIImage(named: "Icon-notification-detail-promos")!
case .userInfoUpdate: return UIImage(named: "Icon-notification-detail-update-data")!
case .supportChat: return UIImage(named: "Icon-notification-detail-support")!
case .newAnnouncement: return UIImage(named: "Icon-notification-detail-advice")!
case .cardVerification: return UIImage(named: "Icon-notification-detail-add-paycard")!
}
}
}
Inside my tableViewCell I have this variable notification which starts to set all values on didSet
switch notification.type {
case NotificationIcons.newPayment.strings:
notificationImageView.image = NotificationIcons.newPayment.image
break
case NotificationIcons.newPaymentMethod.strings:
notificationImageView.image = NotificationIcons.newPaymentMethod.image
break
case NotificationIcons.newOffers.strings:
notificationImageView.image = NotificationIcons.newPaymentMethod.image
break
case NotificationIcons.userInfoUpdate.strings:
notificationImageView.image = NotificationIcons.newPaymentMethod.image
break
case NotificationIcons.supportChat.strings:
notificationImageView.image = NotificationIcons.newPaymentMethod.image
break
case NotificationIcons.newAnnouncement.strings:
notificationImageView.image = NotificationIcons.newPaymentMethod.image
break
case NotificationIcons.cardVerification.strings:
notificationImageView.image = NotificationIcons.newPaymentMethod.image
break
default:
break
}
Firstly, assign rawValue of type String to the NotificationIcons enum, like this:
enum NotificationIcons: String {
case newPayment = "new_payment"
//...
}
Then, modify the switch statement with an initializer:
guard let type = NotificationIcons(rawValue: notification.type) else { return }
notinotificationImageView.image = type.image

How to Zoom .DAE 3D model using ARKit iOS

I have a 3D model with .scn extension. How to zoom it with pinch gesture without virtualobject file from iOS sample Placing Objects application.
Pinch gesture works well with .scn's if its converted from .obj file. But its not working with .dae model.
func addPinchGestureToSceneView() {
pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(scale))
pinchGesture.scale = 1.0;
pinchGesture.delegate = self
self.sceneView.addGestureRecognizer(pinchGesture)
}
private func node(at position: CGPoint) -> SCNNode? {
var hitTestOptions = [SCNHitTestOption: Any]()
hitTestOptions[SCNHitTestOption.boundingBoxOnly] = true
return sceneView.hitTest(position, options: hitTestOptions)
.first(where: { self.getOnlyModelName(name: $0.node.name ?? "") == self.currentmodel.modelname})?
.node
}
#objc func scale(_ gesture: UIPinchGestureRecognizer) {
if self.currentmodel.isZoomEnabled == false{
return
}
let location = gesture.location(in: sceneView)
guard let node = node(at: location)else{return}
// guard let node = node(at: location) else { return }
switch gesture.state {
case .began:
originalScale = node.scale
gesture.scale = CGFloat(node.scale.x)
print("Begin:: \(originalScale)")
case .changed:
guard var originalScale = originalScale else { return }
if gesture.scale > 2.0{
return
}
originalScale.x = Float(gesture.scale)
originalScale.y = Float(gesture.scale)
originalScale.z = Float(gesture.scale)
node.scale = originalScale
case .ended:
guard var originalScale = originalScale else { return }
if gesture.scale > 2.0{
return
}
originalScale.x = Float(gesture.scale)
originalScale.y = Float(gesture.scale)
originalScale.z = Float(gesture.scale)
node.scale = originalScale
gesture.scale = CGFloat(node.scale.x)
default:
gesture.scale = 1.0
originalScale = nil
}
When it's a dae, you might need to try to grab the parent of the node caught in the hit test. I had a similar issue with dae that got solved by getting the parent of the child, or even sometimes the grandparent of the child.

Apple Vision framework – Text extraction from image

I am using Vision framework for iOS 11 to detect text on image.
The texts are getting detected successfully, but how we can get the detected text?
Recognizing text in an image
VNRecognizeTextRequest works starting from iOS 13.0 and macOS 10.15 and higher.
In Apple Vision you can easily extract text from image using VNRecognizeTextRequest class, allowing you to make an image analysis request that finds and recognizes text in an image.
Here's a SwiftUI solution showing you how to do it (tested in Xcode 13.4, iOS 15.5):
import SwiftUI
import Vision
struct ContentView: View {
var body: some View {
ZStack {
Color.black.ignoresSafeArea()
Image("imageText").scaleEffect(0.5)
SomeText()
}
}
}
The logic is the following:
struct SomeText: UIViewRepresentable {
let label = UITextView(frame: .zero)
func makeUIView(context: Context) -> UITextView {
label.backgroundColor = .clear
label.textColor = .systemYellow
label.textAlignment = .center
label.font = .boldSystemFont(ofSize: 25)
return label
}
func updateUIView(_ uiView: UITextView, context: Context) {
let path = Bundle.main.path(forResource: "imageText", ofType: "png")
let url = URL(fileURLWithPath: path!)
let requestHandler = VNImageRequestHandler(url: url, options: [:])
let request = VNRecognizeTextRequest { (request, _) in
guard let obs = request.results as? [VNRecognizedTextObservation]
else { return }
for observation in obs {
let topCan: [VNRecognizedText] = observation.topCandidates(1)
if let recognizedText: VNRecognizedText = topCan.first {
label.text = recognizedText.string
}
}
} // non-realtime asynchronous but accurate text recognition
request.recognitionLevel = VNRequestTextRecognitionLevel.accurate
// nearly realtime but not-accurate text recognition
request.recognitionLevel = VNRequestTextRecognitionLevel.fast
try? requestHandler.perform([request])
}
}
If you wanna know a list of supported languages for recognition, read this post please.
Not exactly a dupe but similar to: Converting a Vision VNTextObservation to a String
You need to either use CoreML or another library to perform OCR (SwiftOCR, etc.)
This will return a overlay image with rectangle box on detected text
Here is the full xcode project
https://github.com/cyruslok/iOS11-Vision-Framework-Demo
Hope it is helpful
// Text Detect
func textDetect(dectect_image:UIImage, display_image_view:UIImageView)->UIImage{
let handler:VNImageRequestHandler = VNImageRequestHandler.init(cgImage: (dectect_image.cgImage)!)
var result_img:UIImage = UIImage.init();
let request:VNDetectTextRectanglesRequest = VNDetectTextRectanglesRequest.init(completionHandler: { (request, error) in
if( (error) != nil){
print("Got Error In Run Text Dectect Request");
}else{
result_img = self.drawRectangleForTextDectect(image: dectect_image,results: request.results as! Array<VNTextObservation>)
}
})
request.reportCharacterBoxes = true
do {
try handler.perform([request])
return result_img;
} catch {
return result_img;
}
}
func drawRectangleForTextDectect(image: UIImage, results:Array<VNTextObservation>) -> UIImage {
let renderer = UIGraphicsImageRenderer(size: image.size)
var t:CGAffineTransform = CGAffineTransform.identity;
t = t.scaledBy( x: image.size.width, y: -image.size.height);
t = t.translatedBy(x: 0, y: -1 );
let img = renderer.image { ctx in
for item in results {
let TextObservation:VNTextObservation = item
ctx.cgContext.setFillColor(UIColor.clear.cgColor)
ctx.cgContext.setStrokeColor(UIColor.green.cgColor)
ctx.cgContext.setLineWidth(1)
ctx.cgContext.addRect(item.boundingBox.applying(t))
ctx.cgContext.drawPath(using: .fillStroke)
for item_2 in TextObservation.characterBoxes!{
let RectangleObservation:VNRectangleObservation = item_2
ctx.cgContext.setFillColor(UIColor.clear.cgColor)
ctx.cgContext.setStrokeColor(UIColor.red.cgColor)
ctx.cgContext.setLineWidth(1)
ctx.cgContext.addRect(RectangleObservation.boundingBox.applying(t))
ctx.cgContext.drawPath(using: .fillStroke)
}
}
}
return img
}

Function in Swift to Append a Pdf file to another Pdf

I created two different pdf files in two different views using following code:
private func toPDF(views: [UIView]) -> NSData? {
if views.isEmpty {return nil}
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, CGRect(x: 0, y: 0, width: 1024, height: 1448), nil)
let context = UIGraphicsGetCurrentContext()
for view in views {
UIGraphicsBeginPDFPage()
view.layer.renderInContext(context!)
}
UIGraphicsEndPDFContext()
return pdfData
}
In the final view I call both files using:
let firstPDF = NSUserDefaults.standardUserDefaults().dataForKey("PDFone")
let secondPDF = NSUserDefaults.standardUserDefaults().dataForKey("PDFtwo")
My question is: Can anyone suggest a function which append the second file to the first one? (Both are in NSData Format)
Swift 4:
func merge(pdfs:Data...) -> Data
{
let out = NSMutableData()
UIGraphicsBeginPDFContextToData(out, .zero, nil)
guard let context = UIGraphicsGetCurrentContext() else {
return out as Data
}
for pdf in pdfs {
guard let dataProvider = CGDataProvider(data: pdf as CFData), let document = CGPDFDocument(dataProvider) else { continue }
for pageNumber in 1...document.numberOfPages {
guard let page = document.page(at: pageNumber) else { continue }
var mediaBox = page.getBoxRect(.mediaBox)
context.beginPage(mediaBox: &mediaBox)
context.drawPDFPage(page)
context.endPage()
}
}
context.closePDF()
UIGraphicsEndPDFContext()
return out as Data
}
This can be done quite easily with PDFKit and its PDFDocument.
I'm using this extension:
import PDFKit
extension PDFDocument {
func addPages(from document: PDFDocument) {
let pageCountAddition = document.pageCount
for pageIndex in 0..<pageCountAddition {
guard let addPage = document.page(at: pageIndex) else {
break
}
self.insert(addPage, at: self.pageCount) // unfortunately this is very very confusing. The index is the page *after* the insertion. Every normal programmer would assume insert at self.pageCount-1
}
}
}
Swift 5:
Merge pdfs like this to keep links, etc...
See answer here

Swift - Associated value or extension for an Enum

General question regarding swift enum.
I want to create an enum of "icon" and "associate" a value to the enum case
enum Icon {
case plane
case arrow
case logo
case flag
}
I want to create an associated image to the enum's value.
And also an associated color to the enum value
So for instance if it was possible to do something like:
extension Icon.plane {
var image = {
get {
return UIImage("plane.png")
}
}
var color = {
get {
return UIColor.greenColor()
}
}
}
var image = Icon.arrow.image // the image associated to the enum
var color = Icon.arrow.color // the color associated to the enum
Is this type of thing possible?
Unfortunately you cannot define static properties based on enum cases, but you can use computed properties and switch to return values for each case:
enum Icon {
case plane
case arrow
case logo
case flag
var image: UIImage {
switch self {
case .plane: return UIImage(named: "plane.png")!
case .arrow: return UIImage(named: "arrow.png")!
case .logo: return UIImage(named: "logo.png")!
case .flag: return UIImage(named: "flag.png")!
}
}
var color: UIColor {
switch self {
case .plane: return UIColor.greenColor()
case .arrow: return UIColor.greenColor()
case .logo: return UIColor.greenColor()
case .flag: return UIColor.greenColor()
}
}
}
// usage
Icon.plane.color
Using enums with associated values combined with switch statements you can be very flexible. A first example:
enum Icon {
case plane(img:UIImage, col:UIColor)
case arrow(img:UIImage, col:UIColor)
case logo(img:UIImage, col:UIColor)
case flag(img:UIImage, col:UIColor)
var values:(img:UIImage,col:UIColor) {
switch self {
case let .plane(image, color):
return (image,color)
case let .arrow(image, color):
return (image,color)
case let .logo(image, color):
return (image,color)
case let .flag(image, color):
return (image,color)
}
}
}
var a = Icon.plane(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
a.values.col
a.values.img
and a second example:
enum Icon {
case plane(img:UIImage, col:UIColor)
case arrow(img:UIImage, col:UIColor)
case logo(img:UIImage, col:UIColor)
case flag(img:UIImage, col:UIColor)
var img:UIImage {
switch self {
case let .plane(image, color):
return image
case let .arrow(image, color):
return image
case let .logo(image, color):
return image
case let .flag(image, color):
return image
}
}
var col:UIColor {
switch self {
case let .plane(image, color):
return color
case let .arrow(image, color):
return color
case let .logo(image, color):
return color
case let .flag(image, color):
return color
}
}
}
var a = Icon.plane(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
a.col
a.img
no need for extensions. And if you really do want static values, you could do this:
struct MyIcon {
static let plane = Icon.plane(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
static let arrow = Icon.arrow(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
static let logo = Icon.logo(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
static let flag = Icon.flag(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
}
MyIcon.arrow.col
which might be tidier than placing the fixed literal values inside a switch statement.
Shorter and safer code:
import UIKit
enum Icon: String {
case plane, arrow, logo, flag
var image: UIImage {
// If the image is not available, provide a default value so we dont force optional unwrapping
return UIImage(named: "\(self.rawValue).png") ?? UIImage()
}
var color: UIColor {
switch self {
case .plane: return UIColor.green
case .arrow: return UIColor.green
case .logo: return UIColor.green
case .flag: return UIColor.green
}
}
}
// Usage
Icon.plane.color
Icon.arrow.image
More cleaner and readable
enum Icon {
case plane
case arrow
case logo
case flag
var image: UIImage {
return value.image
}
var color: UIColor {
return value.color
}
private var value: (image: UIImage, color: UIColor) {
switch self {
case .plane: return (UIImage(named: "plane.png")!, UIColor.green)
case .arrow: return (UIImage(named: "arrow.png")!, UIColor.green)
case .logo: return (UIImage(named: "logo.png")!, UIColor.green)
case .flag: return (UIImage(named: "flag.png")!, UIColor.green)
}
}
}
// Use
Icon.plane.image
Icon.plane.color