diff --git a/.gitignore b/.gitignore index 40b5623..bb6c8b0 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ DerivedData Carthage/Build swiftScan/.DS_Store +.DS_Store diff --git a/README.md b/README.md index 4d0d381..79b6015 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # iOS qrCode、barCode Swift Version - -[![Platform](https://img.shields.io/badge/platform-iOS-red.svg)](https://developer.apple.com/iphone/index.action) -[![Language](http://img.shields.io/badge/language-swift4.0-yellow.svg?style=flat - )](https://en.wikipedia.org/wiki/swift) -[![License](https://img.shields.io/badge/license-MIT-blue.svg)](http://mit-license.org) - + +[![Platform](https://img.shields.io/badge/platform-iOS-red.svg)](https://developer.apple.com/iphone/index.action) +[![Language](http://img.shields.io/badge/language-swift4.0-yellow.svg?style=flat + )](https://en.wikipedia.org/wiki/swift) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](http://mit-license.org) + ### Objective-c Version: **[LBXScan](https://github.com/MxABC/LBXScan)** @@ -42,10 +42,9 @@ ```ruby -source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' use_frameworks! -pod 'swiftScan', '~> 1.1.2' +pod 'swiftScan', :git => 'https://github.com/MxABC/swiftScan.git' ``` diff --git a/Source/Extension/UIImage+swiftScan.swift b/Source/Extension/UIImage+swiftScan.swift new file mode 100644 index 0000000..e86b68f --- /dev/null +++ b/Source/Extension/UIImage+swiftScan.swift @@ -0,0 +1,115 @@ +// +// UIImage+swiftScan.swift +// swiftScan +// +// Create by wooseng with company's MackBook Pro on 2019/9/20. +// Copyright © 2019 xialibing. All rights reserved. +// + + +import UIKit + +internal extension UIImage { + + // 图像裁剪 + func cropping(with rect: CGRect) -> UIImage? { + guard let partRef = cgImage?.cropping(to: rect) else { + return nil + } + return UIImage(cgImage: partRef) + } + + // 图像旋转,失败则返回原图 + func rotation(to orientation: Orientation) -> UIImage { + var rotate: Double = 0.0 + var rect: CGRect + var translateX: CGFloat = 0.0 + var translateY: CGFloat = 0.0 + var scaleX: CGFloat = 1.0 + var scaleY: CGFloat = 1.0 + + switch orientation { + case .left: + rotate = .pi / 2 + rect = CGRect(x: 0, y: 0, width: size.height, height: size.width) + translateX = 0 + translateY = -rect.size.width + scaleY = rect.size.width / rect.size.height + scaleX = rect.size.height / rect.size.width + case .right: + rotate = 3 * .pi / 2 + rect = CGRect(x: 0, y: 0, width: size.height, height: size.width) + translateX = -rect.size.height + translateY = 0 + scaleY = rect.size.width / rect.size.height + scaleX = rect.size.height / rect.size.width + case .down: + rotate = .pi + rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) + translateX = -rect.size.width + translateY = -rect.size.height + default: + rotate = 0.0 + rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) + translateX = 0 + translateY = 0 + } + + guard let cgImage = cgImage else { + return self + } + UIGraphicsBeginImageContext(rect.size) + let context = UIGraphicsGetCurrentContext()! + // 做CTM变换 + context.translateBy(x: 0.0, y: rect.size.height) + context.scaleBy(x: 1.0, y: -1.0) + context.rotate(by: CGFloat(rotate)) + context.translateBy(x: translateX, y: translateY) + context.scaleBy(x: scaleX, y: scaleY) + // 绘制图片 + context.draw(cgImage, in: CGRect(x: 0, y: 0, width: rect.size.width, height: rect.size.height)) + let resultImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return resultImage ?? self + } + + // 图像缩放,失败返回原图 + func resize(quality: CGInterpolationQuality, rate: CGFloat) -> UIImage { + var resized: UIImage? + let width = size.width * rate + let height = size.height * rate + + UIGraphicsBeginImageContext(CGSize(width: width, height: height)) + let context = UIGraphicsGetCurrentContext() + context?.interpolationQuality = quality + draw(in: CGRect(x: 0, y: 0, width: width, height: height)) + resized = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + return resized ?? self + } + +} + +public extension UIImage { + + /// 图像中间增加logo + /// + /// - Parameters: + /// - logoImg: logo图片 + /// - logoSize: logo图像尺寸 + /// - Returns: 添加logo之后的图片,如果添加失败,返回原图 + func addLogo(logoImg: UIImage, logoSize: CGSize) -> UIImage { + UIGraphicsBeginImageContext(size) + draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) + let rect = CGRect(x: size.width / 2 - logoSize.width / 2, + y: size.height / 2 - logoSize.height / 2, + width: logoSize.width, + height: logoSize.height) + logoImg.draw(in: rect) + let resultingImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return resultingImage! + } + +} diff --git a/Source/LBXScanWrapper.swift b/Source/LBXScanWrapper.swift index 97eb0b2..1bb7172 100755 --- a/Source/LBXScanWrapper.swift +++ b/Source/LBXScanWrapper.swift @@ -33,7 +33,7 @@ public struct LBXScanResult { -open class LBXScanWrapper: NSObject,AVCaptureMetadataOutputObjectsDelegate { +open class LBXScanWrapper: NSObject, AVCaptureMetadataOutputObjectsDelegate { let device = AVCaptureDevice.default(for: AVMediaType.video) var input: AVCaptureDeviceInput? @@ -65,7 +65,7 @@ open class LBXScanWrapper: NSObject,AVCaptureMetadataOutputObjectsDelegate { - returns: */ init(videoPreView: UIView, - objType: [AVMetadataObject.ObjectType] = [(AVMetadataObject.ObjectType.qr as NSString) as AVMetadataObject.ObjectType], + objType: [AVMetadataObject.ObjectType] = [.qr, .ean13, .ean8, .code128], isCaptureImg: Bool, cropRect: CGRect = .zero, success: @escaping (([LBXScanResult]) -> Void)) { @@ -107,11 +107,8 @@ open class LBXScanWrapper: NSObject,AVCaptureMetadataOutputObjectsDelegate { // 参数设置 output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) - output.metadataObjectTypes = objType - // output.metadataObjectTypes = [AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code] - if !cropRect.equalTo(CGRect.zero) { // 启动相机后,直接修改该参数无效 output.rectOfInterest = cropRect @@ -267,27 +264,12 @@ open class LBXScanWrapper: NSObject,AVCaptureMetadataOutputObjectsDelegate { setTorch(torch: torch) } - //MARK: ------获取系统默认支持的码的类型 - static func defaultMetaDataObjectTypes() -> [AVMetadataObject.ObjectType] { - var types = - [ - AVMetadataObject.ObjectType.qr, - AVMetadataObject.ObjectType.upce, - AVMetadataObject.ObjectType.code39, - AVMetadataObject.ObjectType.code39Mod43, - AVMetadataObject.ObjectType.ean13, - AVMetadataObject.ObjectType.ean8, - AVMetadataObject.ObjectType.code93, - AVMetadataObject.ObjectType.code128, - AVMetadataObject.ObjectType.pdf417, - AVMetadataObject.ObjectType.aztec, - ] - // if #available(iOS 8.0, *) - - types.append(AVMetadataObject.ObjectType.interleaved2of5) - types.append(AVMetadataObject.ObjectType.itf14) - types.append(AVMetadataObject.ObjectType.dataMatrix) - return types + // 获取系统默认支持的码的类型 + static var defaultMetaDataObjectTypes: [AVMetadataObject.ObjectType] { + return [ + .qr, .upce, .ean13, .ean8, .itf14, .dataMatrix, + .code39, .code39Mod43, .code93, .code128, .pdf417, .aztec, .interleaved2of5 + ] } /** @@ -379,25 +361,25 @@ open class LBXScanWrapper: NSObject,AVCaptureMetadataOutputObjectsDelegate { let image = UIImage(cgImage: cgImage, scale: 1.0, orientation: UIImage.Orientation.up) // Resize without interpolating - return resizeImage(image: image, quality: CGInterpolationQuality.none, rate: 20.0) + return image.resize(quality: .none, rate: 20.0) } // 根据扫描结果,获取图像中得二维码区域图像(如果相机拍摄角度故意很倾斜,获取的图像效果很差) static func getConcreteCodeImage(srcCodeImage: UIImage, codeResult: LBXScanResult) -> UIImage? { let rect = getConcreteCodeRectFromImage(srcCodeImage: srcCodeImage, codeResult: codeResult) - guard !rect.isEmpty, let img = imageByCroppingWithStyle(srcImg: srcCodeImage, rect: rect) else { + guard !rect.isEmpty, let img = srcCodeImage.cropping(with: rect) else { return nil } - return imageRotation(image: img, orientation: UIImage.Orientation.right) + return img.rotation(to: .right) } // 根据二维码的区域截取二维码区域图像 public static func getConcreteCodeImage(srcCodeImage: UIImage, rect: CGRect) -> UIImage? { - guard !rect.isEmpty, let img = imageByCroppingWithStyle(srcImg: srcCodeImage, rect: rect) else { + guard !rect.isEmpty, let img = srcCodeImage.cropping(with: rect) else { return nil } - return imageRotation(image: img, orientation: UIImage.Orientation.right) + return img.rotation(to: .right) } // 获取二维码的图像区域 @@ -440,55 +422,13 @@ open class LBXScanWrapper: NSObject,AVCaptureMetadataOutputObjectsDelegate { height: (yMaxBottom - yMinTop) * imgW) } - //MARK: ----图像处理 - - /** - - @brief 图像中间加logo图片 - @param srcImg 原图像 - @param LogoImage logo图像 - @param logoSize logo图像尺寸 - @return 加Logo的图像 - */ - public static func addImageLogo(srcImg: UIImage, logoImg: UIImage, logoSize: CGSize) -> UIImage { - UIGraphicsBeginImageContext(srcImg.size) - srcImg.draw(in: CGRect(x: 0, y: 0, width: srcImg.size.width, height: srcImg.size.height)) - let rect = CGRect(x: srcImg.size.width / 2 - logoSize.width / 2, - y: srcImg.size.height / 2 - logoSize.height / 2, - width: logoSize.width, - height: logoSize.height) - logoImg.draw(in: rect) - let resultingImage = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() - return resultingImage! - } - - //图像缩放 - static func resizeImage(image: UIImage, quality: CGInterpolationQuality, rate: CGFloat) -> UIImage? { - var resized: UIImage? - let width = image.size.width * rate - let height = image.size.height * rate - - UIGraphicsBeginImageContext(CGSize(width: width, height: height)) - let context = UIGraphicsGetCurrentContext() - context?.interpolationQuality = quality - image.draw(in: CGRect(x: 0, y: 0, width: width, height: height)) - - resized = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() - - return resized - } +} - // 图像裁剪 - static func imageByCroppingWithStyle(srcImg: UIImage, rect: CGRect) -> UIImage? { - guard let imagePartRef = srcImg.cgImage?.cropping(to: rect) else { - return nil - } - return UIImage(cgImage: imagePartRef) - } +//MARK: - 废弃的方法 +extension LBXScanWrapper { // 图像旋转 + @available(*, deprecated, message: "deprecated from 2019-09-20, use UIImage().rotation(to:)") static func imageRotation(image: UIImage, orientation: UIImage.Orientation) -> UIImage { var rotate: Double = 0.0 var rect: CGRect @@ -496,7 +436,7 @@ open class LBXScanWrapper: NSObject,AVCaptureMetadataOutputObjectsDelegate { var translateY: CGFloat = 0.0 var scaleX: CGFloat = 1.0 var scaleY: CGFloat = 1.0 - + switch orientation { case .left: rotate = .pi / 2 @@ -523,7 +463,7 @@ open class LBXScanWrapper: NSObject,AVCaptureMetadataOutputObjectsDelegate { translateX = 0 translateY = 0 } - + UIGraphicsBeginImageContext(rect.size) let context = UIGraphicsGetCurrentContext()! // 做CTM变换 @@ -531,11 +471,53 @@ open class LBXScanWrapper: NSObject,AVCaptureMetadataOutputObjectsDelegate { context.scaleBy(x: 1.0, y: -1.0) context.rotate(by: CGFloat(rotate)) context.translateBy(x: translateX, y: translateY) - + context.scaleBy(x: scaleX, y: scaleY) // 绘制图片 context.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: rect.size.width, height: rect.size.height)) return UIGraphicsGetImageFromCurrentImageContext()! } + // 图像裁剪 + @available(*, deprecated, message: "deprecated from 2019-09-20, use UIImage().cropping(with:)") + static func imageByCroppingWithStyle(srcImg: UIImage, rect: CGRect) -> UIImage? { + guard let imagePartRef = srcImg.cgImage?.cropping(to: rect) else { + return nil + } + return UIImage(cgImage: imagePartRef) + } + + // 图像缩放 + @available(*, deprecated, message: "deprecated from 2019-09-20, use UIImage().resize(quality:, rate:)") + static func resizeImage(image: UIImage, quality: CGInterpolationQuality, rate: CGFloat) -> UIImage? { + var resized: UIImage? + let width = image.size.width * rate + let height = image.size.height * rate + + UIGraphicsBeginImageContext(CGSize(width: width, height: height)) + let context = UIGraphicsGetCurrentContext() + context?.interpolationQuality = quality + image.draw(in: CGRect(x: 0, y: 0, width: width, height: height)) + + resized = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + return resized + } + + // 图像中间增加logologo图像尺寸 + @available(*, deprecated, message: "deprecated from 2019-09-20, use UIImage().addLogo(logoImg:, logoSize:)") + public static func addImageLogo(srcImg: UIImage, logoImg: UIImage, logoSize: CGSize) -> UIImage { + UIGraphicsBeginImageContext(srcImg.size) + srcImg.draw(in: CGRect(x: 0, y: 0, width: srcImg.size.width, height: srcImg.size.height)) + let rect = CGRect(x: srcImg.size.width / 2 - logoSize.width / 2, + y: srcImg.size.height / 2 - logoSize.height / 2, + width: logoSize.width, + height: logoSize.height) + logoImg.draw(in: rect) + let resultingImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return resultingImage! + } + } diff --git a/swiftScan.podspec b/swiftScan.podspec index 756ae9e..ac21733 100644 --- a/swiftScan.podspec +++ b/swiftScan.podspec @@ -8,5 +8,5 @@ Pod::Spec.new do |s| s.platform = :ios, '8.0' s.source = {:git => 'https://github.com/MxABC/swiftScan.git', :tag => s.version} s.ios.deployment_target = "8.0" - s.source_files = 'Source/*.swift' + s.source_files = 'Source/*.swift', 'Source/**/*.swift' end diff --git a/swiftScan.xcodeproj/project.pbxproj b/swiftScan.xcodeproj/project.pbxproj index dcb0ed1..f80442c 100755 --- a/swiftScan.xcodeproj/project.pbxproj +++ b/swiftScan.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 7D42B9B71C05EE9A0084D045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7D42B9B61C05EE9A0084D045 /* Assets.xcassets */; }; 7D42B9BA1C05EE9A0084D045 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7D42B9B81C05EE9A0084D045 /* LaunchScreen.storyboard */; }; 7DA82E091C19CE5E0028B5DB /* logo.JPG in Resources */ = {isa = PBXBuildFile; fileRef = 7DA82E081C19CE5E0028B5DB /* logo.JPG */; }; + 94128A462334D1EA00D6179E /* UIImage+swiftScan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94128A452334D1EA00D6179E /* UIImage+swiftScan.swift */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -67,6 +68,7 @@ 7D46320C1C18683A00D70CF1 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = ""; }; 7D46320D1C18683A00D70CF1 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = ""; }; 7DA82E081C19CE5E0028B5DB /* logo.JPG */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = logo.JPG; sourceTree = ""; }; + 94128A452334D1EA00D6179E /* UIImage+swiftScan.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+swiftScan.swift"; sourceTree = ""; }; D6DC96F61F6D0C0200E1CCEB /* SwiftScanner.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftScanner.h; sourceTree = ""; }; D6DC96F71F6D0C0200E1CCEB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ @@ -85,6 +87,7 @@ 488928DC1C1A7BE4005A8F83 /* Source */ = { isa = PBXGroup; children = ( + 94128A442334D18200D6179E /* Extension */, 48D3BBD01C70104100823F87 /* LBXPermissions.swift */, 488928DD1C1A7BE4005A8F83 /* LBXScanLineAnimation.swift */, 488928DE1C1A7BE4005A8F83 /* LBXScanNetAnimation.swift */, @@ -135,6 +138,14 @@ path = swiftScan; sourceTree = ""; }; + 94128A442334D18200D6179E /* Extension */ = { + isa = PBXGroup; + children = ( + 94128A452334D1EA00D6179E /* UIImage+swiftScan.swift */, + ); + path = Extension; + sourceTree = ""; + }; D6DC96F51F6D0C0200E1CCEB /* SwiftScanner */ = { isa = PBXGroup; children = ( @@ -230,6 +241,7 @@ 7D42B9B21C05EE9A0084D045 /* ViewController.swift in Sources */, 488928E51C1A7BE4005A8F83 /* LBXScanView.swift in Sources */, 488928E81C1A7BE4005A8F83 /* LBXScanWrapper.swift in Sources */, + 94128A462334D1EA00D6179E /* UIImage+swiftScan.swift in Sources */, 7D42B9B01C05EE9A0084D045 /* AppDelegate.swift in Sources */, 73FF0B901CF545FE0083F169 /* MyCodeViewController.swift in Sources */, 488928E71C1A7BE4005A8F83 /* LBXScanViewStyle.swift in Sources */, diff --git a/swiftScan/MyCodeViewController.swift b/swiftScan/MyCodeViewController.swift index b35ba34..28071be 100644 --- a/swiftScan/MyCodeViewController.swift +++ b/swiftScan/MyCodeViewController.swift @@ -73,7 +73,7 @@ class MyCodeViewController: UIViewController { let qrImg = LBXScanWrapper.createCode(codeType: "CIQRCodeGenerator", codeString: "lbxia20091227@foxmail.com", size: qrImgView.bounds.size, qrColor: UIColor.black, bkColor: UIColor.white) let logoImg = UIImage(named: "logo.JPG") - qrImgView.image = LBXScanWrapper.addImageLogo(srcImg: qrImg!, logoImg: logoImg!, logoSize: CGSize(width: 30, height: 30)) + qrImgView.image = qrImg?.addLogo(logoImg: logoImg!, logoSize: CGSize(width: 30, height: 30)) } func createCode128() {