LoginSignup
0
0

More than 3 years have passed since last update.

Azure Computer Vision API-v3.0(OCR) をSwiftで

Posted at

概要

Azure Computer Vision APIをSwiftにてサンプルコードを作成しました。
リファレンスにてObjCはあるもののSwiftがないため参考になれば幸いです。

APIをcallするだけなので、どの言語でもできます

環境

Swift 5
xcode11

Podfile
pod 'Alamofire', '~> 4.7.3'

事前準備

GUIにてsubscription keyendpointを取得

サンプルコード

ViewController
private func executeOCR() {
    // imageViewにて表示しているものをOCR処理する想定
    guard let image = self.imageView.image else { return }

    // それぞれ取得したものをStringで
    let subscriptionKey = "subscription key"
    let endpoint = "endpoint"

    let urlString = endpoint + "vision/v3.0/ocr"
    var request = URLRequest(url: URL(string: urlString)!)
    request.addValue(subscriptionKey, forHTTPHeaderField: "Ocp-Apim-Subscription-Key")

    // languageは適切なものに変更
    let params: [String: String] = [
        "language":"ja",
        "detectOrientation":"true"
    ]

    Alamofire.upload(multipartFormData: { multipartFormData in
        var compressionQuality: CGFloat = 1.0
        if var imageData = image.jpegData(compressionQuality: compressionQuality) {
            var imageDataCount = imageData.count

            repeat {
                imageData = image.jpegData(compressionQuality: compressionQuality)!
                imageDataCount = imageData.count
                compressionQuality -= 0.1
            } while imageDataCount > 4000000
            multipartFormData.append(imageData, withName: "image", fileName: "file.jpeg", mimeType: "image/jpeg")
        }

        for (key, value) in params {
            multipartFormData.append(value.data(using: .utf8)!, withName: key)
        }
    }, with: request) { encodingResult in
        switch encodingResult {
        case.success(let upload, _ ,_):
            upload
                .responseData { responseData in
                    let parsedResponse = try? JSONDecoder().decode(OCRResponse.self, from: responseData.data!)
                    // 後述
                    let output = self.getResponseWord(response: parsedResponse)
                    print(output)
            }
        case.failure(let _): break
        }
    }
}

OCRResponse
struct OCRResponse: Codable {
    var language: String?
    var orientation: String?
    var regions: [Regions]?
//  textAngleはIntのはずだがStringで返される時もあったため消しています
}

struct Regions: Codable {
    var boundingBox: String?
    var lines: [Lines]?
}

struct Lines: Codable {
    var boundingBox: String?
    var words: [Words?]
}

struct Words: Codable {
    var boundingBox: String?
    var text: String?
}

iPhoneの画像拡張子事情

SS: .png
カメラ: .heic

Q:
・・・heic?

A:
iOS11から実装されていたもので「HEIF」形式の拡張子、それまでは「JPEG」形式
この形式は「高画質のまま軽量化」した写真の保存形式
その拡張子が.heic

一部コード解説

repeat

repeat {
    imageData = image.jpegData(compressionQuality: compressionQuality)!
    imageDataCount = imageData.count
    compressionQuality -= 0.1
} while imageDataCount > 4000000

リファレンスにも記載があるが、4MBが上限となっている。
HEIF形式で保存される.heicですら4MBを超えることがある。(せっかく軽量化しているのに・・・
そのため、4MBを超えるようであれば10%ずつ質をさげている。

updataメソッド

Alamofire.upload

これはDefaultでHTTPメソッドがPOSTで行ってくれる

getResponseWord

private func getResponseWord(response: OCRResponse?) -> String {
    guard let response = response else { return "" }
    var output = ""

    response.regions?.forEach { regions in
        regions.lines?.forEach { lines in
            lines.words.forEach { words in
                output += words?.text ?? ""
            }
            output += "\n"
        }
    }
}

ここで各自必要なものを取得。
上記サンプルは1ワード毎に改行したものを返している。

補足

無料期間は30日
文字読み取れて嬉しい

質問等あればお気軽に!
速さ重視で作ったのでOptinal関連やrepeat文なぜ?等は目を瞑って下さい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0