Upgrade to Pro — share decks privately, control downloads, hide ads and more …

「QRコード読み取り?楽勝ですよ😙」=>「AVFoundationを信じたおれがバカだった😇」 / iOSDC 2018

monoqlo
September 01, 2018

「QRコード読み取り?楽勝ですよ😙」=>「AVFoundationを信じたおれがバカだった😇」 / iOSDC 2018

iOSDC 2018 2018/09/01 14:40〜 Track B レギュラートーク(15分)

monoqlo

September 01, 2018
Tweet

More Decks by monoqlo

Other Decks in Programming

Transcript

  1. • ECI • ߏ଄త࿈઀ • FNC1 • (ऴ୺ύλʔϯ) • ਺ࣈ

    • ӳ਺ࣈ • 8ϏοτόΠτ • ׽ࣈ Ϟʔυ = σʔλΛ֨ೲ͢Δܗࣜ • ѹॖޮ཰޲্Λ໨తͱ͠ɺଟ਺ͷϞʔυ͕ఆٛ͞Ε͍ͯΔ • QRίʔυੜ੒࣌ɺσʔλʹ߹Θͤͯ࠷దͳ΋ͷΛબ୒͢Δ • ϔομʔͱͯ͠จࣈ਺ࢦࣔࢠͱͱ΋ʹσʔλʹ෇Ճ͢Δ • ૊Έ߹Θͤͯ࢖༻Մʢex. ӳ਺ࣈ + ׽ࣈʣ ߏ଄త࿈઀
  2. • ਺ࣈ • ӳ਺ࣈ • 8ϏοτόΠτ • ׽ࣈ • ECI

    • ߏ଄త࿈઀ • FNC1 • (ऴ୺ύλʔϯ) Ϟʔυ = σʔλΛ֨ೲ͢Δܗࣜ • ѹॖޮ཰޲্Λ໨తͱ͠ɺଟ਺ͷϞʔυ͕ఆٛ͞Ε͍ͯΔ • QRίʔυੜ੒࣌ɺσʔλʹ߹Θͤͯ࠷దͳ΋ͷΛબ୒͢Δ • ϔομʔͱͯ͠จࣈ਺ࢦࣔࢠͱͱ΋ʹσʔλʹ෇Ճ͢Δ • ૊Έ߹Θͤͯ࢖༻Մʢex. ӳ਺ࣈ + ׽ࣈʣ ߏ଄త࿈઀
  3. ϓϩύςΟ var corners: [CGPoint] A Swift array of corner points.

    var stringValue: String? Returns the error corrected data decoded into a human- readable string.
  4. γϯϘϧҐஔ/߹ܭ਺ͱύϦςΟ͕औΕΔ @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) { guard

    let _ = result else { return } // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠ // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ // - kResultMetadataTypeStructuredAppendSequence // - kResultMetadataTypeStructuredAppendParity guard let metaData = result.resultMetadata, let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int, let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int else { return } // sequence: ಡΈऔͬͨQRίʔυͷ൪߸ 4bit + τʔλϧͷQRίʔυ਺ 4bit let bit = String(sequenceValue, radix: 2) let pad = String(repeating: "0", count: (8 - bit.count)) let sequence = pad + bit let current = Int(sequence.prefix(4), radix: 2)! let total = Int(sequence.suffix(from: 4), radix: 2)! … } @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) { guard let _ = result else { return } // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠ // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ // - kResultMetadataTypeStructuredAppendSequence // - kResultMetadataTypeStructuredAppendParity
  5. γϯϘϧҐஔ/߹ܭ਺ͱύϦςΟ͕औΕΔ @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) { guard

    let _ = result else { return } // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠ // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ // - kResultMetadataTypeStructuredAppendSequence // - kResultMetadataTypeStructuredAppendParity guard let metaData = result.resultMetadata, let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int, let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int else { return } // sequence: ಡΈऔͬͨQRίʔυͷ൪߸ 4bit + τʔλϧͷQRίʔυ਺ 4bit let bit = String(sequenceValue, radix: 2) let pad = String(repeating: "0", count: (8 - bit.count)) let sequence = pad + bit let current = Int(sequence.prefix(4), radix: 2)! let total = Int(sequence.suffix(from: 4), radix: 2)! … } @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) { guard let _ = result else { return } // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠ // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ // - kResultMetadataTypeStructuredAppendSequence // - kResultMetadataTypeStructuredAppendParity guard let metaData = result.resultMetadata, let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int, let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int else { return }
  6. γϯϘϧҐஔ/߹ܭ਺ͱύϦςΟ͕औΕΔ @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) { guard

    let _ = result else { return } // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠ // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ // - kResultMetadataTypeStructuredAppendSequence // - kResultMetadataTypeStructuredAppendParity guard let metaData = result.resultMetadata, let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int, let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int else { return } // sequence: ಡΈऔͬͨQRίʔυͷ൪߸ 4bit + τʔλϧͷQRίʔυ਺ 4bit let bit = String(sequenceValue, radix: 2) let pad = String(repeating: "0", count: (8 - bit.count)) let sequence = pad + bit let current = Int(sequence.prefix(4), radix: 2)! let total = Int(sequence.suffix(from: 4), radix: 2)! … } @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) { guard let _ = result else { return } // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠ // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ // - kResultMetadataTypeStructuredAppendSequence // - kResultMetadataTypeStructuredAppendParity guard let metaData = result.resultMetadata, let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int, let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int else { return } // sequence: ಡΈऔͬͨQRίʔυͷ൪߸ 4bit + τʔλϧͷQRίʔυ਺ 4bit let bit = String(sequenceValue, radix: 2) let pad = String(repeating: "0", count: (8 - bit.count)) let sequence = pad + bit let current = Int(sequence.prefix(4), radix: 2)! let total = Int(sequence.suffix(from: 4), radix: 2)! … }
  7. γϯϘϧҐஔ/߹ܭ਺ͱύϦςΟ͕औΕΔ @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) { guard

    let _ = result else { return } // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠ // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ // - kResultMetadataTypeStructuredAppendSequence // - kResultMetadataTypeStructuredAppendParity guard let metaData = result.resultMetadata, let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int, let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int else { return } // sequence: ಡΈऔͬͨQRίʔυͷ൪߸ 4bit + τʔλϧͷQRίʔυ਺ 4bit let bit = String(sequenceValue, radix: 2) let pad = String(repeating: "0", count: (8 - bit.count)) let sequence = pad + bit let current = Int(sequence.prefix(4), radix: 2)! let total = Int(sequence.suffix(from: 4), radix: 2)! … } @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) { guard let _ = result else { return } // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠ // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ // - kResultMetadataTypeStructuredAppendSequence // - kResultMetadataTypeStructuredAppendParity // sequence: ಡΈऔͬͨQRίʔυͷ൪߸ 4bit + τʔλϧͷQRίʔυ਺ 4bit let bit = String(sequenceValue, radix: 2) let pad = String(repeating: "0", count: (8 - bit.count)) let sequence = pad + bit let current = Int(sequence.prefix(4), radix: 2)! let total = Int(sequence.suffix(from: 4), radix: 2)! … } guard let metaData = result.resultMetadata, let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int, let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int else { return }
  8. iOS ͷόʔδϣϯγΣΞભҠ      ೥݄ ݄ ݄

    ݄ ݄ ೥݄ ݄ ݄ ݄ iOS 11 iOS 10 iOS 9 or Earlier ※ 2018೥9݄͸༧ଌ
  9. ϓϩύςΟ var corners: [CGPoint] A Swift array of corner points.

    var stringValue: String? Returns the error corrected data decoded into a human- readable string. var descriptor: CIBarcodeDescriptor? A barcode description for use in Core Image.
  10. CIQRCodeDescriptor ͱ͸ • iOS 11 Ͱ௥Ճ͞ΕͨڧྗͳΫϥε • ந৅Ϋϥε CIBarcodeDescriptor ͷαϒΫϥε

    • QRίʔυΛੜ੒͢ΔͨΊʹඞཁे෼ͳσʔλΛ࣋ͭ • CIFilter Ͱ QRίʔυը૾Λੜ੒͢Δ͜ͱ΋Ͱ͖Δ
  11. CIQRCodeDescriptor ͱ͸ • iOS 11 Ͱ௥Ճ͞ΕͨڧྗͳΫϥε • ந৅Ϋϥε CIBarcodeDescriptor ͷαϒΫϥε

    • CIFilter Ͱ QRίʔυը૾Λੜ੒͢Δ͜ͱ΋Ͱ͖Δ func generateQRCodeImage(from descriptor: CIQRCodeDescriptor) -> UIImage? { let inputParams: [String: Any] = ["inputBarcodeDescriptor": descriptor] let barcodeCreationFilter = CIFilter(name: "CIBarcodeGenerator", parameters: inputParams) guard let outputImage = barcodeCreationFilter?.outputImage, let cgImage = CIContext().createCGImage(outputImage, from: outputImage.extent) else { return nil } return UIImage(cgImage: cgImage) }
  12. େࣄͳͷ͸͜ͷ 2 ͭ var errorCorrectedPayload: Data The error-corrected payload containing

    the data encoded in the QR code. var symbolVersion: Int The version of the QR code.
  13. େࣄͳͷ͸͜ͷ 2 ͭ var errorCorrectedPayload: Data The error-corrected payload containing

    the data encoded in the QR code. var symbolVersion: Int The version of the QR code.
  14. େࣄͳͷ͸͜ͷ 2 ͭ var errorCorrectedPayload: Data The error-corrected payload containing

    the data encoded in the QR code. var symbolVersion: Int The version of the QR code.
  15. iOS 11 Ҏ߱ͷੈքͰ͸ AVMetadata Machine ReadableCode Object 2. CIQRCodeDescriptor #errorCorrectedPayload

    ΛऔΓग़͢ σίʔυ͢Δ 1. AVFoundation ͰಡΈऔΔ ͕Μ͹ͬͯ 3.
  16. ·ͱΊʢiOS 11 Ҏ߱ͷੈքʣ 1. AVCaptureSession ͰಡΈऔΔ AVMetadata Machine ReadableCode Object

    2. CIQRCodeDescriptor #errorCorrectedPayload ΛऔΓग़͢ ͕Μ͹ͬͯσίʔυ͢Δ 3.