├── OCR-master ├── README.md ├── idcard.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── idcard │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Capture.h │ ├── Capture.m │ ├── IDCardViewController.h │ ├── IDCardViewController.m │ ├── IdInfo.h │ ├── IdInfo.m │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── id.png │ │ │ ├── id_120x120.png │ │ │ ├── id_152x152.png │ │ │ ├── id_29x29.png │ │ │ ├── id_40x40.png │ │ │ ├── id_58x58.png │ │ │ ├── id_76x76.png │ │ │ ├── id_80x80-1.png │ │ │ └── id_80x80.png │ │ └── LaunchImage.launchimage │ │ │ ├── 1136.png │ │ │ ├── 960.png │ │ │ └── Contents.json │ ├── QuartzHelpLibrary.h │ ├── QuartzHelpLibrary.m │ ├── UserDefaults.h │ ├── UserDefaults.m │ ├── ViewController.h │ ├── ViewController.m │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── idcard-Info.plist │ ├── idcard-Prefix.pch │ └── main.m ├── idcardTests │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── idcardTests-Info.plist │ └── idcardTests.m └── libexidcard │ ├── commondef.h │ ├── dicts │ └── zocr0.lib │ ├── excards.h │ └── libexidcardios.a └── README.md /OCR-master/README.md: -------------------------------------------------------------------------------- 1 | # OCR 2 | 光学文字识别身份证 Optical Character Recognition 3 | -------------------------------------------------------------------------------- /OCR-master/idcard.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | FD56E14A19E8EBA500811C76 /* UserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = FD56E14919E8EBA500811C76 /* UserDefaults.m */; }; 11 | FDD0461D1AD92D9B00C30B04 /* libexidcardios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FDD0461C1AD92D9B00C30B04 /* libexidcardios.a */; }; 12 | FDD046231AD9310200C30B04 /* zocr0.lib in Resources */ = {isa = PBXBuildFile; fileRef = FDD046211AD9310200C30B04 /* zocr0.lib */; }; 13 | FDE45DB219E818B700309145 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDE45DB119E818B700309145 /* Foundation.framework */; }; 14 | FDE45DB419E818B700309145 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDE45DB319E818B700309145 /* CoreGraphics.framework */; }; 15 | FDE45DB619E818B700309145 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDE45DB519E818B700309145 /* UIKit.framework */; }; 16 | FDE45DBC19E818B700309145 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = FDE45DBA19E818B700309145 /* InfoPlist.strings */; }; 17 | FDE45DBE19E818B700309145 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FDE45DBD19E818B700309145 /* main.m */; }; 18 | FDE45DC219E818B700309145 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FDE45DC119E818B700309145 /* AppDelegate.m */; }; 19 | FDE45DCB19E818B800309145 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FDE45DCA19E818B800309145 /* ViewController.m */; }; 20 | FDE45DCD19E818B800309145 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FDE45DCC19E818B800309145 /* Images.xcassets */; }; 21 | FDE45DD419E818B800309145 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDE45DD319E818B800309145 /* XCTest.framework */; }; 22 | FDE45DD519E818B800309145 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDE45DB119E818B700309145 /* Foundation.framework */; }; 23 | FDE45DD619E818B800309145 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDE45DB519E818B700309145 /* UIKit.framework */; }; 24 | FDE45DDE19E818B800309145 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = FDE45DDC19E818B800309145 /* InfoPlist.strings */; }; 25 | FDE45DE019E818B800309145 /* idcardTests.m in Sources */ = {isa = PBXBuildFile; fileRef = FDE45DDF19E818B800309145 /* idcardTests.m */; }; 26 | FDE45DEB19E81B1F00309145 /* IDCardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FDE45DEA19E81B1F00309145 /* IDCardViewController.m */; }; 27 | FDE45DF019E81B8200309145 /* Capture.m in Sources */ = {isa = PBXBuildFile; fileRef = FDE45DED19E81B8200309145 /* Capture.m */; }; 28 | FDE45DF419E81C7B00309145 /* IdInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = FDE45DF319E81C7B00309145 /* IdInfo.m */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXContainerItemProxy section */ 32 | FDE45DD719E818B800309145 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = FDE45DA619E818B700309145 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = FDE45DAD19E818B700309145; 37 | remoteInfo = idcard; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXFileReference section */ 42 | 38D0C9141AF9A61A00078294 /* excards.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = excards.h; sourceTree = ""; }; 43 | FD56E14819E8EBA500811C76 /* UserDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserDefaults.h; sourceTree = ""; }; 44 | FD56E14919E8EBA500811C76 /* UserDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserDefaults.m; sourceTree = ""; }; 45 | FDD0461C1AD92D9B00C30B04 /* libexidcardios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libexidcardios.a; sourceTree = ""; }; 46 | FDD046211AD9310200C30B04 /* zocr0.lib */ = {isa = PBXFileReference; lastKnownFileType = file; path = zocr0.lib; sourceTree = ""; }; 47 | FDE45DAE19E818B700309145 /* idcard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = idcard.app; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | FDE45DB119E818B700309145 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 49 | FDE45DB319E818B700309145 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 50 | FDE45DB519E818B700309145 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 51 | FDE45DB919E818B700309145 /* idcard-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "idcard-Info.plist"; sourceTree = ""; }; 52 | FDE45DBB19E818B700309145 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 53 | FDE45DBD19E818B700309145 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 54 | FDE45DBF19E818B700309145 /* idcard-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "idcard-Prefix.pch"; sourceTree = ""; }; 55 | FDE45DC019E818B700309145 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 56 | FDE45DC119E818B700309145 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 57 | FDE45DC919E818B800309145 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 58 | FDE45DCA19E818B800309145 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 59 | FDE45DCC19E818B800309145 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 60 | FDE45DD219E818B800309145 /* idcardTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = idcardTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | FDE45DD319E818B800309145 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 62 | FDE45DDB19E818B800309145 /* idcardTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "idcardTests-Info.plist"; sourceTree = ""; }; 63 | FDE45DDD19E818B800309145 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 64 | FDE45DDF19E818B800309145 /* idcardTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = idcardTests.m; sourceTree = ""; }; 65 | FDE45DE919E81B1F00309145 /* IDCardViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDCardViewController.h; sourceTree = ""; }; 66 | FDE45DEA19E81B1F00309145 /* IDCardViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IDCardViewController.m; sourceTree = ""; }; 67 | FDE45DEC19E81B8200309145 /* Capture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Capture.h; sourceTree = ""; }; 68 | FDE45DED19E81B8200309145 /* Capture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Capture.m; sourceTree = ""; }; 69 | FDE45DF219E81C7B00309145 /* IdInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IdInfo.h; sourceTree = ""; }; 70 | FDE45DF319E81C7B00309145 /* IdInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IdInfo.m; sourceTree = ""; }; 71 | /* End PBXFileReference section */ 72 | 73 | /* Begin PBXFrameworksBuildPhase section */ 74 | FDE45DAB19E818B700309145 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | FDE45DB419E818B700309145 /* CoreGraphics.framework in Frameworks */, 79 | FDD0461D1AD92D9B00C30B04 /* libexidcardios.a in Frameworks */, 80 | FDE45DB619E818B700309145 /* UIKit.framework in Frameworks */, 81 | FDE45DB219E818B700309145 /* Foundation.framework in Frameworks */, 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | FDE45DCF19E818B800309145 /* Frameworks */ = { 86 | isa = PBXFrameworksBuildPhase; 87 | buildActionMask = 2147483647; 88 | files = ( 89 | FDE45DD419E818B800309145 /* XCTest.framework in Frameworks */, 90 | FDE45DD619E818B800309145 /* UIKit.framework in Frameworks */, 91 | FDE45DD519E818B800309145 /* Foundation.framework in Frameworks */, 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | /* End PBXFrameworksBuildPhase section */ 96 | 97 | /* Begin PBXGroup section */ 98 | FDD0461F1AD9310200C30B04 /* dicts */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | FDD046211AD9310200C30B04 /* zocr0.lib */, 102 | ); 103 | path = dicts; 104 | sourceTree = ""; 105 | }; 106 | FDE45DA519E818B700309145 = { 107 | isa = PBXGroup; 108 | children = ( 109 | FDE45DF519E81CA000309145 /* libexidcard */, 110 | FDE45DB719E818B700309145 /* idcard */, 111 | FDE45DD919E818B800309145 /* idcardTests */, 112 | FDE45DB019E818B700309145 /* Frameworks */, 113 | FDE45DAF19E818B700309145 /* Products */, 114 | ); 115 | sourceTree = ""; 116 | }; 117 | FDE45DAF19E818B700309145 /* Products */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | FDE45DAE19E818B700309145 /* idcard.app */, 121 | FDE45DD219E818B800309145 /* idcardTests.xctest */, 122 | ); 123 | name = Products; 124 | sourceTree = ""; 125 | }; 126 | FDE45DB019E818B700309145 /* Frameworks */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | FDE45DB119E818B700309145 /* Foundation.framework */, 130 | FDE45DB319E818B700309145 /* CoreGraphics.framework */, 131 | FDE45DB519E818B700309145 /* UIKit.framework */, 132 | FDE45DD319E818B800309145 /* XCTest.framework */, 133 | ); 134 | name = Frameworks; 135 | sourceTree = ""; 136 | }; 137 | FDE45DB719E818B700309145 /* idcard */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | FD56E14819E8EBA500811C76 /* UserDefaults.h */, 141 | FD56E14919E8EBA500811C76 /* UserDefaults.m */, 142 | FDE45DF219E81C7B00309145 /* IdInfo.h */, 143 | FDE45DF319E81C7B00309145 /* IdInfo.m */, 144 | FDE45DEC19E81B8200309145 /* Capture.h */, 145 | FDE45DED19E81B8200309145 /* Capture.m */, 146 | FDE45DC019E818B700309145 /* AppDelegate.h */, 147 | FDE45DC119E818B700309145 /* AppDelegate.m */, 148 | FDE45DC919E818B800309145 /* ViewController.h */, 149 | FDE45DCA19E818B800309145 /* ViewController.m */, 150 | FDE45DCC19E818B800309145 /* Images.xcassets */, 151 | FDE45DB819E818B700309145 /* Supporting Files */, 152 | FDE45DE919E81B1F00309145 /* IDCardViewController.h */, 153 | FDE45DEA19E81B1F00309145 /* IDCardViewController.m */, 154 | ); 155 | path = idcard; 156 | sourceTree = ""; 157 | }; 158 | FDE45DB819E818B700309145 /* Supporting Files */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | FDE45DB919E818B700309145 /* idcard-Info.plist */, 162 | FDE45DBA19E818B700309145 /* InfoPlist.strings */, 163 | FDE45DBD19E818B700309145 /* main.m */, 164 | FDE45DBF19E818B700309145 /* idcard-Prefix.pch */, 165 | ); 166 | name = "Supporting Files"; 167 | sourceTree = ""; 168 | }; 169 | FDE45DD919E818B800309145 /* idcardTests */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | FDE45DDF19E818B800309145 /* idcardTests.m */, 173 | FDE45DDA19E818B800309145 /* Supporting Files */, 174 | ); 175 | path = idcardTests; 176 | sourceTree = ""; 177 | }; 178 | FDE45DDA19E818B800309145 /* Supporting Files */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | FDE45DDB19E818B800309145 /* idcardTests-Info.plist */, 182 | FDE45DDC19E818B800309145 /* InfoPlist.strings */, 183 | ); 184 | name = "Supporting Files"; 185 | sourceTree = ""; 186 | }; 187 | FDE45DF519E81CA000309145 /* libexidcard */ = { 188 | isa = PBXGroup; 189 | children = ( 190 | 38D0C9141AF9A61A00078294 /* excards.h */, 191 | FDD0461F1AD9310200C30B04 /* dicts */, 192 | FDD0461C1AD92D9B00C30B04 /* libexidcardios.a */, 193 | ); 194 | path = libexidcard; 195 | sourceTree = ""; 196 | }; 197 | /* End PBXGroup section */ 198 | 199 | /* Begin PBXNativeTarget section */ 200 | FDE45DAD19E818B700309145 /* idcard */ = { 201 | isa = PBXNativeTarget; 202 | buildConfigurationList = FDE45DE319E818B800309145 /* Build configuration list for PBXNativeTarget "idcard" */; 203 | buildPhases = ( 204 | FDE45DAA19E818B700309145 /* Sources */, 205 | FDE45DAB19E818B700309145 /* Frameworks */, 206 | FDE45DAC19E818B700309145 /* Resources */, 207 | ); 208 | buildRules = ( 209 | ); 210 | dependencies = ( 211 | ); 212 | name = idcard; 213 | productName = idcard; 214 | productReference = FDE45DAE19E818B700309145 /* idcard.app */; 215 | productType = "com.apple.product-type.application"; 216 | }; 217 | FDE45DD119E818B800309145 /* idcardTests */ = { 218 | isa = PBXNativeTarget; 219 | buildConfigurationList = FDE45DE619E818B800309145 /* Build configuration list for PBXNativeTarget "idcardTests" */; 220 | buildPhases = ( 221 | FDE45DCE19E818B800309145 /* Sources */, 222 | FDE45DCF19E818B800309145 /* Frameworks */, 223 | FDE45DD019E818B800309145 /* Resources */, 224 | ); 225 | buildRules = ( 226 | ); 227 | dependencies = ( 228 | FDE45DD819E818B800309145 /* PBXTargetDependency */, 229 | ); 230 | name = idcardTests; 231 | productName = idcardTests; 232 | productReference = FDE45DD219E818B800309145 /* idcardTests.xctest */; 233 | productType = "com.apple.product-type.bundle.unit-test"; 234 | }; 235 | /* End PBXNativeTarget section */ 236 | 237 | /* Begin PBXProject section */ 238 | FDE45DA619E818B700309145 /* Project object */ = { 239 | isa = PBXProject; 240 | attributes = { 241 | LastUpgradeCheck = 0510; 242 | ORGANIZATIONNAME = hxg; 243 | TargetAttributes = { 244 | FDE45DD119E818B800309145 = { 245 | DevelopmentTeam = 96K9CR85U4; 246 | TestTargetID = FDE45DAD19E818B700309145; 247 | }; 248 | }; 249 | }; 250 | buildConfigurationList = FDE45DA919E818B700309145 /* Build configuration list for PBXProject "idcard" */; 251 | compatibilityVersion = "Xcode 3.2"; 252 | developmentRegion = English; 253 | hasScannedForEncodings = 0; 254 | knownRegions = ( 255 | en, 256 | Base, 257 | ); 258 | mainGroup = FDE45DA519E818B700309145; 259 | productRefGroup = FDE45DAF19E818B700309145 /* Products */; 260 | projectDirPath = ""; 261 | projectRoot = ""; 262 | targets = ( 263 | FDE45DAD19E818B700309145 /* idcard */, 264 | FDE45DD119E818B800309145 /* idcardTests */, 265 | ); 266 | }; 267 | /* End PBXProject section */ 268 | 269 | /* Begin PBXResourcesBuildPhase section */ 270 | FDE45DAC19E818B700309145 /* Resources */ = { 271 | isa = PBXResourcesBuildPhase; 272 | buildActionMask = 2147483647; 273 | files = ( 274 | FDD046231AD9310200C30B04 /* zocr0.lib in Resources */, 275 | FDE45DCD19E818B800309145 /* Images.xcassets in Resources */, 276 | FDE45DBC19E818B700309145 /* InfoPlist.strings in Resources */, 277 | ); 278 | runOnlyForDeploymentPostprocessing = 0; 279 | }; 280 | FDE45DD019E818B800309145 /* Resources */ = { 281 | isa = PBXResourcesBuildPhase; 282 | buildActionMask = 2147483647; 283 | files = ( 284 | FDE45DDE19E818B800309145 /* InfoPlist.strings in Resources */, 285 | ); 286 | runOnlyForDeploymentPostprocessing = 0; 287 | }; 288 | /* End PBXResourcesBuildPhase section */ 289 | 290 | /* Begin PBXSourcesBuildPhase section */ 291 | FDE45DAA19E818B700309145 /* Sources */ = { 292 | isa = PBXSourcesBuildPhase; 293 | buildActionMask = 2147483647; 294 | files = ( 295 | FD56E14A19E8EBA500811C76 /* UserDefaults.m in Sources */, 296 | FDE45DCB19E818B800309145 /* ViewController.m in Sources */, 297 | FDE45DC219E818B700309145 /* AppDelegate.m in Sources */, 298 | FDE45DF419E81C7B00309145 /* IdInfo.m in Sources */, 299 | FDE45DBE19E818B700309145 /* main.m in Sources */, 300 | FDE45DF019E81B8200309145 /* Capture.m in Sources */, 301 | FDE45DEB19E81B1F00309145 /* IDCardViewController.m in Sources */, 302 | ); 303 | runOnlyForDeploymentPostprocessing = 0; 304 | }; 305 | FDE45DCE19E818B800309145 /* Sources */ = { 306 | isa = PBXSourcesBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | FDE45DE019E818B800309145 /* idcardTests.m in Sources */, 310 | ); 311 | runOnlyForDeploymentPostprocessing = 0; 312 | }; 313 | /* End PBXSourcesBuildPhase section */ 314 | 315 | /* Begin PBXTargetDependency section */ 316 | FDE45DD819E818B800309145 /* PBXTargetDependency */ = { 317 | isa = PBXTargetDependency; 318 | target = FDE45DAD19E818B700309145 /* idcard */; 319 | targetProxy = FDE45DD719E818B800309145 /* PBXContainerItemProxy */; 320 | }; 321 | /* End PBXTargetDependency section */ 322 | 323 | /* Begin PBXVariantGroup section */ 324 | FDE45DBA19E818B700309145 /* InfoPlist.strings */ = { 325 | isa = PBXVariantGroup; 326 | children = ( 327 | FDE45DBB19E818B700309145 /* en */, 328 | ); 329 | name = InfoPlist.strings; 330 | sourceTree = ""; 331 | }; 332 | FDE45DDC19E818B800309145 /* InfoPlist.strings */ = { 333 | isa = PBXVariantGroup; 334 | children = ( 335 | FDE45DDD19E818B800309145 /* en */, 336 | ); 337 | name = InfoPlist.strings; 338 | sourceTree = ""; 339 | }; 340 | /* End PBXVariantGroup section */ 341 | 342 | /* Begin XCBuildConfiguration section */ 343 | FDE45DE119E818B800309145 /* Debug */ = { 344 | isa = XCBuildConfiguration; 345 | buildSettings = { 346 | ALWAYS_SEARCH_USER_PATHS = NO; 347 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 348 | CLANG_CXX_LIBRARY = "libc++"; 349 | CLANG_ENABLE_MODULES = YES; 350 | CLANG_ENABLE_OBJC_ARC = YES; 351 | CLANG_WARN_BOOL_CONVERSION = YES; 352 | CLANG_WARN_CONSTANT_CONVERSION = YES; 353 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 354 | CLANG_WARN_EMPTY_BODY = YES; 355 | CLANG_WARN_ENUM_CONVERSION = YES; 356 | CLANG_WARN_INT_CONVERSION = YES; 357 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 358 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 359 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 360 | COPY_PHASE_STRIP = NO; 361 | GCC_C_LANGUAGE_STANDARD = gnu99; 362 | GCC_DYNAMIC_NO_PIC = NO; 363 | GCC_OPTIMIZATION_LEVEL = 0; 364 | GCC_PREPROCESSOR_DEFINITIONS = ( 365 | "DEBUG=1", 366 | "$(inherited)", 367 | ); 368 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 369 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 370 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 371 | GCC_WARN_UNDECLARED_SELECTOR = YES; 372 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 373 | GCC_WARN_UNUSED_FUNCTION = YES; 374 | GCC_WARN_UNUSED_VARIABLE = YES; 375 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 376 | ONLY_ACTIVE_ARCH = YES; 377 | SDKROOT = iphoneos; 378 | TARGETED_DEVICE_FAMILY = "1,2"; 379 | }; 380 | name = Debug; 381 | }; 382 | FDE45DE219E818B800309145 /* Release */ = { 383 | isa = XCBuildConfiguration; 384 | buildSettings = { 385 | ALWAYS_SEARCH_USER_PATHS = NO; 386 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 387 | CLANG_CXX_LIBRARY = "libc++"; 388 | CLANG_ENABLE_MODULES = YES; 389 | CLANG_ENABLE_OBJC_ARC = YES; 390 | CLANG_WARN_BOOL_CONVERSION = YES; 391 | CLANG_WARN_CONSTANT_CONVERSION = YES; 392 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 393 | CLANG_WARN_EMPTY_BODY = YES; 394 | CLANG_WARN_ENUM_CONVERSION = YES; 395 | CLANG_WARN_INT_CONVERSION = YES; 396 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 397 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 398 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 399 | COPY_PHASE_STRIP = YES; 400 | ENABLE_NS_ASSERTIONS = NO; 401 | GCC_C_LANGUAGE_STANDARD = gnu99; 402 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 403 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 404 | GCC_WARN_UNDECLARED_SELECTOR = YES; 405 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 406 | GCC_WARN_UNUSED_FUNCTION = YES; 407 | GCC_WARN_UNUSED_VARIABLE = YES; 408 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 409 | SDKROOT = iphoneos; 410 | TARGETED_DEVICE_FAMILY = "1,2"; 411 | VALIDATE_PRODUCT = YES; 412 | }; 413 | name = Release; 414 | }; 415 | FDE45DE419E818B800309145 /* Debug */ = { 416 | isa = XCBuildConfiguration; 417 | buildSettings = { 418 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 419 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 420 | CODE_SIGN_IDENTITY = "iPhone Developer"; 421 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 422 | ENABLE_BITCODE = NO; 423 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 424 | GCC_PREFIX_HEADER = "idcard/idcard-Prefix.pch"; 425 | INFOPLIST_FILE = "idcard/idcard-Info.plist"; 426 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 427 | LIBRARY_SEARCH_PATHS = ( 428 | "$(inherited)", 429 | "$(PROJECT_DIR)/libexidcard", 430 | ); 431 | PRODUCT_BUNDLE_IDENTIFIER = cc.tg.fsdf; 432 | PRODUCT_NAME = "$(TARGET_NAME)"; 433 | PROVISIONING_PROFILE = ""; 434 | WRAPPER_EXTENSION = app; 435 | }; 436 | name = Debug; 437 | }; 438 | FDE45DE519E818B800309145 /* Release */ = { 439 | isa = XCBuildConfiguration; 440 | buildSettings = { 441 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 442 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 443 | CODE_SIGN_IDENTITY = "iPhone Developer"; 444 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 445 | ENABLE_BITCODE = NO; 446 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 447 | GCC_PREFIX_HEADER = "idcard/idcard-Prefix.pch"; 448 | INFOPLIST_FILE = "idcard/idcard-Info.plist"; 449 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 450 | LIBRARY_SEARCH_PATHS = ( 451 | "$(inherited)", 452 | "$(PROJECT_DIR)/libexidcard", 453 | ); 454 | PRODUCT_BUNDLE_IDENTIFIER = cc.tg.fsdf; 455 | PRODUCT_NAME = "$(TARGET_NAME)"; 456 | PROVISIONING_PROFILE = ""; 457 | WRAPPER_EXTENSION = app; 458 | }; 459 | name = Release; 460 | }; 461 | FDE45DE719E818B800309145 /* Debug */ = { 462 | isa = XCBuildConfiguration; 463 | buildSettings = { 464 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/idcard.app/idcard"; 465 | FRAMEWORK_SEARCH_PATHS = ( 466 | "$(SDKROOT)/Developer/Library/Frameworks", 467 | "$(inherited)", 468 | "$(DEVELOPER_FRAMEWORKS_DIR)", 469 | ); 470 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 471 | GCC_PREFIX_HEADER = "idcard/idcard-Prefix.pch"; 472 | GCC_PREPROCESSOR_DEFINITIONS = ( 473 | "DEBUG=1", 474 | "$(inherited)", 475 | ); 476 | INFOPLIST_FILE = "idcardTests/idcardTests-Info.plist"; 477 | PRODUCT_NAME = "$(TARGET_NAME)"; 478 | TEST_HOST = "$(BUNDLE_LOADER)"; 479 | WRAPPER_EXTENSION = xctest; 480 | }; 481 | name = Debug; 482 | }; 483 | FDE45DE819E818B800309145 /* Release */ = { 484 | isa = XCBuildConfiguration; 485 | buildSettings = { 486 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/idcard.app/idcard"; 487 | FRAMEWORK_SEARCH_PATHS = ( 488 | "$(SDKROOT)/Developer/Library/Frameworks", 489 | "$(inherited)", 490 | "$(DEVELOPER_FRAMEWORKS_DIR)", 491 | ); 492 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 493 | GCC_PREFIX_HEADER = "idcard/idcard-Prefix.pch"; 494 | INFOPLIST_FILE = "idcardTests/idcardTests-Info.plist"; 495 | PRODUCT_NAME = "$(TARGET_NAME)"; 496 | TEST_HOST = "$(BUNDLE_LOADER)"; 497 | WRAPPER_EXTENSION = xctest; 498 | }; 499 | name = Release; 500 | }; 501 | /* End XCBuildConfiguration section */ 502 | 503 | /* Begin XCConfigurationList section */ 504 | FDE45DA919E818B700309145 /* Build configuration list for PBXProject "idcard" */ = { 505 | isa = XCConfigurationList; 506 | buildConfigurations = ( 507 | FDE45DE119E818B800309145 /* Debug */, 508 | FDE45DE219E818B800309145 /* Release */, 509 | ); 510 | defaultConfigurationIsVisible = 0; 511 | defaultConfigurationName = Release; 512 | }; 513 | FDE45DE319E818B800309145 /* Build configuration list for PBXNativeTarget "idcard" */ = { 514 | isa = XCConfigurationList; 515 | buildConfigurations = ( 516 | FDE45DE419E818B800309145 /* Debug */, 517 | FDE45DE519E818B800309145 /* Release */, 518 | ); 519 | defaultConfigurationIsVisible = 0; 520 | defaultConfigurationName = Release; 521 | }; 522 | FDE45DE619E818B800309145 /* Build configuration list for PBXNativeTarget "idcardTests" */ = { 523 | isa = XCConfigurationList; 524 | buildConfigurations = ( 525 | FDE45DE719E818B800309145 /* Debug */, 526 | FDE45DE819E818B800309145 /* Release */, 527 | ); 528 | defaultConfigurationIsVisible = 0; 529 | defaultConfigurationName = Release; 530 | }; 531 | /* End XCConfigurationList section */ 532 | }; 533 | rootObject = FDE45DA619E818B700309145 /* Project object */; 534 | } 535 | -------------------------------------------------------------------------------- /OCR-master/idcard.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /OCR-master/idcard/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // idcard 4 | // 5 | // Created by hxg on 16-4-10. 6 | // Copyright (c) 2016年 林英伟. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /OCR-master/idcard/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // idcard 4 | // 5 | // Created by hxg on 16-4-10. 6 | // Copyright (c) 2016年 林英伟. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "UserDefaults.h" 11 | #import "ViewController.h" 12 | 13 | @implementation AppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 16 | { 17 | [UserDefaults initialize]; 18 | // Override point for customization after application launch. 19 | 20 | ViewController *vc = [[ViewController alloc] init]; 21 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc]; 22 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 23 | self.window.rootViewController = nav; 24 | [self.window makeKeyAndVisible]; 25 | 26 | return YES; 27 | } 28 | 29 | - (void)applicationWillResignActive:(UIApplication *)application 30 | { 31 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 32 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 33 | } 34 | 35 | - (void)applicationDidEnterBackground:(UIApplication *)application 36 | { 37 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 38 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 39 | } 40 | 41 | - (void)applicationWillEnterForeground:(UIApplication *)application 42 | { 43 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 44 | } 45 | 46 | - (void)applicationDidBecomeActive:(UIApplication *)application 47 | { 48 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 49 | } 50 | 51 | - (void)applicationWillTerminate:(UIApplication *)application 52 | { 53 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /OCR-master/idcard/Capture.h: -------------------------------------------------------------------------------- 1 | // 2 | // Capture.h 3 | // idcard 4 | // 5 | // Created by hxg on 16-4-10. 6 | // Copyright (c) 2016年 林英伟. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import "IdInfo.h" 13 | #import "excards.h" 14 | 15 | @protocol CaptureDelegate 16 | 17 | @optional 18 | 19 | - (void)idCardRecognited:(IdInfo*)idInfo; 20 | 21 | @end 22 | 23 | 24 | @interface Capture : NSObject 25 | { 26 | AVCaptureDeviceInput *_videoInput; 27 | AVCaptureConnection *_focusConnection; 28 | } 29 | 30 | @property (strong,nonatomic) AVCaptureVideoPreviewLayer *previewLayer; 31 | @property (strong,nonatomic) AVCaptureSession *captureSession; 32 | @property (strong,nonatomic) AVCaptureStillImageOutput *stillImageOutput; 33 | @property (strong,nonatomic) AVCaptureVideoDataOutput *videooutput; 34 | @property (strong,nonatomic) UIImage *stillImage; 35 | @property (strong,nonatomic) NSNumber *outPutSetting; 36 | @property (weak, nonatomic) id delegate; 37 | @property (nonatomic)BOOL verify; 38 | 39 | /** 40 | * @brief Add video input: front or back camera: 41 | * AVCaptureDevicePositionBack 42 | * AVCaptureDevicePositionFront 43 | */ 44 | - (void)addVideoInput:(AVCaptureDevicePosition)_campos; 45 | 46 | /** 47 | * @brief Add video output 48 | */ 49 | - (void)addVideoOutput; 50 | 51 | /** 52 | * @brief Add preview layer 53 | */ 54 | - (void)addVideoPreviewLayer; 55 | 56 | //聚焦 57 | - (void)focusInPoint:(CGPoint)devicePoint; 58 | - (void)focusWithMode:(AVCaptureFocusMode)focusMode exposeWithMode:(AVCaptureExposureMode)exposureMode atDevicePoint:(CGPoint)point monitorSubjectAreaChange:(BOOL)monitorSubjectAreaChange; 59 | 60 | -(void)setvideoScale; 61 | 62 | @end -------------------------------------------------------------------------------- /OCR-master/idcard/Capture.m: -------------------------------------------------------------------------------- 1 | // 2 | // Capture.m 3 | // idcard 4 | // 5 | // Created by hxg on 16-4-10. 6 | // Copyright (c) 2016年 林英伟. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "Capture.h" 12 | 13 | @implementation Capture 14 | { 15 | unsigned char* _buffer; 16 | IdInfo * _lastIdInfo; 17 | } 18 | 19 | @synthesize captureSession; 20 | @synthesize previewLayer; 21 | @synthesize stillImageOutput; 22 | @synthesize stillImage; 23 | @synthesize outPutSetting; 24 | @synthesize delegate; 25 | @synthesize verify; 26 | 27 | 28 | #pragma mark - Init 29 | 30 | - (id)init 31 | { 32 | if ((self = [super init])) 33 | { 34 | [self setCaptureSession:[[AVCaptureSession alloc] init]]; 35 | // Init default values 36 | //self.captureSession.sessionPreset = AVCaptureSessionPresetMedium; 37 | //AVCaptureSessionPresetHigh 38 | //AVCaptureSessionPresetPhoto 39 | [self.captureSession setSessionPreset:AVCaptureSessionPresetHigh]; 40 | //kCVPixelFormatType_420YpCbCr8BiPlanarFullRange 41 | //kCVPixelFormatType_32BGRA 42 | self.outPutSetting = [NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange]; 43 | self.verify = true; 44 | 45 | } 46 | 47 | return self; 48 | } 49 | 50 | #pragma mark - Public Functions 51 | 52 | - (void)addVideoPreviewLayer 53 | { 54 | [self setPreviewLayer:[[AVCaptureVideoPreviewLayer alloc] initWithSession:[self captureSession]]]; 55 | [[self previewLayer] setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 56 | 57 | } 58 | 59 | - (void)addVideoInput:(AVCaptureDevicePosition)_campos 60 | { 61 | AVCaptureDevice *videoDevice=nil; 62 | 63 | NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; 64 | 65 | if (_campos == AVCaptureDevicePositionBack) 66 | { 67 | for (AVCaptureDevice *device in devices) 68 | { 69 | if ([device position] == AVCaptureDevicePositionBack) 70 | { 71 | if ([device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) 72 | { 73 | NSError *error = nil; 74 | if ([device lockForConfiguration:&error]) 75 | { 76 | device.focusMode = AVCaptureFocusModeContinuousAutoFocus; 77 | [device unlockForConfiguration]; 78 | } 79 | } 80 | videoDevice = device; 81 | } 82 | } 83 | } 84 | else if (_campos == AVCaptureDevicePositionFront) 85 | { 86 | for (AVCaptureDevice *device in devices) 87 | { 88 | if ([device position] == AVCaptureDevicePositionFront) 89 | { 90 | if ([device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) 91 | { 92 | NSError *error = nil; 93 | if ([device lockForConfiguration:&error]) 94 | { 95 | device.focusMode = AVCaptureFocusModeContinuousAutoFocus; 96 | [device unlockForConfiguration]; 97 | } 98 | } 99 | videoDevice = device; 100 | } 101 | } 102 | } 103 | else 104 | NSLog(@"Error setting camera device position."); 105 | 106 | 107 | if (videoDevice) 108 | { 109 | NSError *error; 110 | 111 | AVCaptureDeviceInput *videoIn = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error]; 112 | 113 | if (!error) 114 | { 115 | if ([[self captureSession] canAddInput:videoIn]) 116 | { 117 | [[self captureSession] addInput:videoIn]; 118 | _videoInput = videoIn; 119 | } 120 | else 121 | NSLog(@"Couldn't add video input"); 122 | } 123 | else 124 | NSLog(@"Couldn't create video input"); 125 | } 126 | else 127 | NSLog(@"Couldn't create video capture device"); 128 | } 129 | 130 | 131 | - (void)addVideoOutput 132 | { 133 | // Create a VideoDataOutput and add it to the session 134 | self.videooutput = [[AVCaptureVideoDataOutput alloc] init]; 135 | 136 | [[self captureSession] addOutput:self.videooutput]; 137 | 138 | // Specify the pixel format 139 | self.videooutput.videoSettings = [NSDictionary dictionaryWithObject:outPutSetting forKey:(id)kCVPixelBufferPixelFormatTypeKey]; 140 | self.videooutput.alwaysDiscardsLateVideoFrames = YES; 141 | 142 | // Configure your output. 143 | dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL); 144 | 145 | [self.videooutput setSampleBufferDelegate:self queue:queue]; 146 | 147 | } 148 | 149 | -(void)setvideoScale 150 | { 151 | _focusConnection = [self.videooutput connectionWithMediaType:AVMediaTypeVideo]; 152 | _focusConnection.videoScaleAndCropFactor = 1; 153 | [[self previewLayer] setAffineTransform:CGAffineTransformMakeScale(1, 1)]; 154 | } 155 | 156 | 157 | #pragma mark - Private Functions 158 | 159 | - (void)addStillImageOutput 160 | { 161 | [self setStillImageOutput:[[AVCaptureStillImageOutput alloc] init]]; 162 | 163 | NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey,nil]; 164 | 165 | [[self stillImageOutput] setOutputSettings:outputSettings]; 166 | 167 | AVCaptureConnection *videoConnection = nil; 168 | 169 | for (AVCaptureConnection *connection in [[self stillImageOutput] connections]) 170 | { 171 | for (AVCaptureInputPort *port in [connection inputPorts]) 172 | { 173 | if ([[port mediaType] isEqual:AVMediaTypeVideo] ) 174 | { 175 | videoConnection = connection; 176 | break; 177 | } 178 | } 179 | if (videoConnection) 180 | { 181 | [videoConnection setVideoMinFrameDuration:CMTimeMake(1, 15)]; 182 | break; 183 | } 184 | } 185 | 186 | [[self captureSession] addOutput:[self stillImageOutput]]; 187 | } 188 | 189 | - (void)captureStillImage 190 | { 191 | AVCaptureConnection *videoConnection = nil; 192 | 193 | for (AVCaptureConnection *connection in [[self stillImageOutput] connections]) 194 | { 195 | for (AVCaptureInputPort *port in [connection inputPorts]) 196 | { 197 | if ([[port mediaType] isEqual:AVMediaTypeVideo]) 198 | { 199 | videoConnection = connection; 200 | break; 201 | } 202 | } 203 | if (videoConnection) { 204 | break; 205 | } 206 | } 207 | } 208 | 209 | - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 210 | { 211 | static int n = 0; 212 | if (++n % 2) 213 | return; 214 | 215 | if ([outPutSetting isEqualToNumber:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange]] || 216 | [outPutSetting isEqualToNumber:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange]] ) 217 | { 218 | if([delegate respondsToSelector:@selector(idCardRecognited:)]) 219 | { 220 | IdInfo *idInfo = [self idCardRecognit:sampleBuffer]; 221 | if (idInfo !=nil && [idInfo isOK]) 222 | { 223 | [self.delegate idCardRecognited:idInfo]; 224 | } 225 | } 226 | } 227 | else 228 | { 229 | NSLog(@"Error output video settings"); 230 | } 231 | } 232 | 233 | - (IdInfo *)idCardRecognit:(CMSampleBufferRef)sampleBuffer 234 | { 235 | CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 236 | IdInfo *idInfo = nil; 237 | // Lock the image buffer 238 | if (CVPixelBufferLockBaseAddress(imageBuffer, 0) == kCVReturnSuccess) 239 | { 240 | size_t width= CVPixelBufferGetWidth(imageBuffer); 241 | size_t height = CVPixelBufferGetHeight(imageBuffer); 242 | 243 | CVPlanarPixelBufferInfo_YCbCrBiPlanar *planar = CVPixelBufferGetBaseAddress(imageBuffer); 244 | size_t offset = NSSwapBigIntToHost(planar->componentInfoY.offset); 245 | size_t rowBytes = NSSwapBigIntToHost(planar->componentInfoY.rowBytes); 246 | unsigned char* baseAddress = (unsigned char *)CVPixelBufferGetBaseAddress(imageBuffer); 247 | unsigned char* pixelAddress = baseAddress + offset; 248 | 249 | /* 250 | size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 251 | size_t buffeSize = CVPixelBufferGetDataSize(imageBuffer); 252 | NSLog(@"bytesPerRow[%zu] width[%zu] height[%zu] buffeSize[%zu] offset[%zu]", 253 | bytesPerRow, width, height, buffeSize, offset); 254 | NSLog(@"componentInfoY.rowBytes[%zu]", rowBytes); 255 | NSLog(@"componentInfoCbCr.rowBytes[%zu]", uvrowBytes); 256 | */ 257 | if (_buffer == NULL) 258 | _buffer = (unsigned char*)malloc(sizeof(unsigned char) * width * height); 259 | 260 | memcpy(_buffer, pixelAddress, sizeof(unsigned char) * width * height); 261 | 262 | CVPixelBufferUnlockBaseAddress(imageBuffer, 0); 263 | 264 | unsigned char pResult[1024]; 265 | 266 | 267 | int ret = EXCARDS_RecoIDCardData(_buffer, (int)width, (int)height, (int)rowBytes, (int)8, (char*)pResult, sizeof(pResult)); 268 | if (ret <= 0) 269 | { 270 | // NSLog(@"IDCardRecApi,ret[%d]", ret); 271 | } 272 | else 273 | { 274 | // NSLog(@"ret=[%d]", ret); 275 | char ctype; 276 | char content[256]; 277 | int xlen; 278 | int i = 0; 279 | 280 | idInfo = [[IdInfo alloc] init]; 281 | ctype = pResult[i++]; 282 | idInfo.type = ctype; 283 | while(i < ret){ 284 | ctype = pResult[i++]; 285 | for(xlen = 0; i < ret; ++i){ 286 | if(pResult[i] == ' ') { ++i; break; } 287 | content[xlen++] = pResult[i]; 288 | } 289 | content[xlen] = 0; 290 | if(xlen){ 291 | NSStringEncoding gbkEncoding =CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000); 292 | if(ctype == 0x21) 293 | idInfo.code = [NSString stringWithCString:(char *)content encoding:gbkEncoding]; 294 | else if(ctype == 0x22) 295 | idInfo.name = [NSString stringWithCString:(char *)content encoding:gbkEncoding]; 296 | else if(ctype == 0x23) 297 | idInfo.gender = [NSString stringWithCString:(char *)content encoding:gbkEncoding]; 298 | else if(ctype == 0x24) 299 | idInfo.nation = [NSString stringWithCString:(char *)content encoding:gbkEncoding]; 300 | else if(ctype == 0x25) 301 | idInfo.address = [NSString stringWithCString:(char *)content encoding:gbkEncoding]; 302 | else if(ctype == 0x26) 303 | idInfo.issue = [NSString stringWithCString:(char *)content encoding:gbkEncoding]; 304 | else if(ctype == 0x27) 305 | idInfo.valid = [NSString stringWithCString:(char *)content encoding:gbkEncoding]; 306 | } 307 | } 308 | if (self.verify) 309 | { 310 | if (_lastIdInfo == nil) 311 | { 312 | _lastIdInfo = idInfo; 313 | idInfo = nil; 314 | } 315 | else 316 | { 317 | if (![_lastIdInfo isEqual:idInfo]) 318 | { 319 | _lastIdInfo = idInfo; 320 | idInfo = nil; 321 | } 322 | } 323 | } 324 | if ([idInfo isOK]) 325 | { 326 | //NSLog(@"[%@]", [idInfo toString]); 327 | } 328 | } 329 | } 330 | 331 | return idInfo; 332 | printf("."); 333 | //NSLog(@"end of idCardRecognit"); 334 | } 335 | 336 | 337 | /** 338 | * 点击后对焦 339 | * 340 | * @param devicePoint 点击的point 341 | */ 342 | - (void)focusInPoint:(CGPoint)devicePoint 343 | { 344 | NSLog(@"%f,%f",devicePoint.x,devicePoint.y); 345 | [self focusWithMode:AVCaptureFocusModeContinuousAutoFocus exposeWithMode:AVCaptureExposureModeContinuousAutoExposure atDevicePoint:devicePoint monitorSubjectAreaChange:YES]; 346 | } 347 | 348 | - (void)focusWithMode:(AVCaptureFocusMode)focusMode exposeWithMode:(AVCaptureExposureMode)exposureMode atDevicePoint:(CGPoint)point monitorSubjectAreaChange:(BOOL)monitorSubjectAreaChange 349 | { 350 | 351 | dispatch_queue_t queue = dispatch_queue_create("myQueue11", NULL); 352 | 353 | dispatch_async(queue, ^{ 354 | AVCaptureDevice *device = [_videoInput device]; 355 | NSError *error = nil; 356 | if ([device lockForConfiguration:&error]) 357 | { 358 | if ([device isFocusPointOfInterestSupported] && [device isFocusModeSupported:focusMode]) 359 | { 360 | [device setFocusMode:focusMode]; 361 | [device setFocusPointOfInterest:point]; 362 | } 363 | if ([device isExposurePointOfInterestSupported] && [device isExposureModeSupported:exposureMode]) 364 | { 365 | [device setExposureMode:exposureMode]; 366 | [device setExposurePointOfInterest:point]; 367 | } 368 | [device setSubjectAreaChangeMonitoringEnabled:monitorSubjectAreaChange]; 369 | [device unlockForConfiguration]; 370 | } 371 | else 372 | { 373 | NSLog(@"%@", error); 374 | } 375 | }); 376 | } 377 | 378 | 379 | 380 | 381 | - (NSString *)documentDirectory 382 | { 383 | return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 384 | } 385 | 386 | #pragma mark - Dealloc 387 | 388 | - (void)dealloc 389 | { 390 | [[self captureSession] stopRunning]; 391 | 392 | previewLayer = nil; 393 | captureSession = nil; 394 | stillImageOutput = nil; 395 | stillImage = nil; 396 | outPutSetting = nil; 397 | delegate = nil; 398 | } 399 | 400 | @end -------------------------------------------------------------------------------- /OCR-master/idcard/IDCardViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // IDCardViewController.h 3 | // idcard 4 | // 5 | // Created by hxg on 16-4-10. 6 | // Copyright (c) 2016年 林英伟. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Capture.h" 11 | 12 | @interface IDCardViewController : UIViewController 13 | { 14 | Capture *_capture; 15 | UIView *_cameraView; 16 | unsigned char* _buffer; 17 | 18 | //聚焦View 19 | UIView *_focusView; 20 | 21 | UILabel *codeLabel; //身份证号 22 | UILabel *nameLabel; //姓名 23 | UILabel *genderLabel; //性别 24 | UILabel *nationLabel; //民族 25 | UILabel *addressLabel; //地址 26 | UILabel *issueLabel; //签发机关 27 | UILabel *validLabel; //地址 28 | } 29 | @property (weak, nonatomic) id delegate; 30 | @property (nonatomic, retain) UIToolbar *toolbar; 31 | @property (nonatomic)BOOL verify; 32 | @end 33 | -------------------------------------------------------------------------------- /OCR-master/idcard/IDCardViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // IDCardViewController.m 3 | // idcard 4 | // 5 | // Created by hxg on 16-4-10. 6 | // Copyright (c) 2016年 林英伟. All rights reserved. 7 | // 8 | @import MobileCoreServices; 9 | @import ImageIO; 10 | #import "IDCardViewController.h" 11 | #import "IdInfo.h" 12 | 13 | @interface IDCardViewController () 14 | 15 | @end 16 | 17 | @implementation IDCardViewController 18 | @synthesize verify = _verify; 19 | 20 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 21 | { 22 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 23 | if (self) { 24 | // Custom initialization 25 | } 26 | return self; 27 | } 28 | 29 | static Boolean init_flag = false; 30 | - (void)viewDidLoad 31 | { 32 | [super viewDidLoad]; 33 | // Do any additional setup after loading the view. 34 | 35 | if (!init_flag) 36 | { 37 | const char *thePath = [[[NSBundle mainBundle] resourcePath] UTF8String]; 38 | int ret = EXCARDS_Init(thePath); 39 | if (ret != 0) 40 | { 41 | NSLog(@"Init Failed!ret=[%d]", ret); 42 | } 43 | 44 | init_flag = true; 45 | } 46 | 47 | self.toolbar = [UIToolbar new]; 48 | _toolbar.barStyle = UIBarStyleDefault; 49 | 50 | // size up the toolbar and set its frame 51 | [_toolbar sizeToFit]; 52 | CGFloat toolbarHeight = [_toolbar frame].size.height; 53 | CGRect frame = self.view.bounds; 54 | [_toolbar setFrame:CGRectMake(CGRectGetMinX(frame), 55 | CGRectGetMinY(frame) + CGRectGetHeight(frame) - toolbarHeight, 56 | CGRectGetWidth(frame), 57 | toolbarHeight)]; 58 | 59 | [self.view addSubview:_toolbar]; 60 | 61 | // Create spacing 62 | UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; 63 | 64 | UIBarButtonItem *close = [[UIBarButtonItem alloc] 65 | initWithBarButtonSystemItem:UIBarButtonSystemItemStop 66 | target:self 67 | action:@selector(closeAction)]; 68 | 69 | UIBarButtonItem *start = [[UIBarButtonItem alloc] 70 | initWithBarButtonSystemItem:UIBarButtonSystemItemReply 71 | target:self 72 | action:@selector(startAction)]; 73 | 74 | NSMutableArray *items = [NSMutableArray arrayWithObjects: close, flex, start, flex, nil]; 75 | [self.toolbar setItems:items animated:NO]; 76 | } 77 | 78 | - (void)closeAction 79 | { 80 | [self removeCapture]; 81 | [self dismissViewControllerAnimated: YES completion:nil]; 82 | if(init_flag){ 83 | EXCARDS_Done(); 84 | init_flag = false; 85 | } 86 | } 87 | 88 | - (void)startAction 89 | { 90 | dispatch_async(dispatch_get_main_queue(), ^(void) { 91 | [nameLabel setText:@""]; 92 | [genderLabel setText:@""]; 93 | [nationLabel setText:@""]; 94 | [addressLabel setText:@""]; 95 | [codeLabel setText:@""]; 96 | [issueLabel setText:@""]; 97 | [validLabel setText:@""]; 98 | }); 99 | 100 | [[_capture captureSession] startRunning]; 101 | } 102 | 103 | -(void) viewDidUnload 104 | { 105 | if (_buffer != NULL) 106 | { 107 | free(_buffer); 108 | _buffer = NULL; 109 | } 110 | } 111 | 112 | - (void)viewWillAppear:(BOOL)animated 113 | { 114 | [self initCapture]; 115 | } 116 | 117 | - (void)didReceiveMemoryWarning 118 | { 119 | [super didReceiveMemoryWarning]; 120 | // Dispose of any resources that can be recreated. 121 | } 122 | 123 | 124 | #pragma mark - Capture 125 | 126 | - (void)initCapture 127 | { 128 | // init capture manager 129 | _capture = [[Capture alloc] init]; 130 | 131 | _capture.delegate = self; 132 | _capture.verify = self.verify; 133 | 134 | // set video streaming quality 135 | // AVCaptureSessionPresetHigh 1280x720 136 | // AVCaptureSessionPresetPhoto 852x640 137 | // AVCaptureSessionPresetMedium 480x360 138 | _capture.captureSession.sessionPreset = AVCaptureSessionPresetHigh; 139 | 140 | //kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange 141 | //kCVPixelFormatType_420YpCbCr8BiPlanarFullRange 142 | //kCVPixelFormatType_32BGRA 143 | [_capture setOutPutSetting:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange]]; 144 | 145 | // AVCaptureDevicePositionBack 146 | // AVCaptureDevicePositionFront 147 | [_capture addVideoInput:AVCaptureDevicePositionBack]; 148 | 149 | [_capture addVideoOutput]; 150 | [_capture addVideoPreviewLayer]; 151 | 152 | CGRect layerRect = self.view.bounds; 153 | [[_capture previewLayer] setOpaque: 0]; 154 | [[_capture previewLayer] setBounds:layerRect]; 155 | [[_capture previewLayer] setPosition:CGPointMake( CGRectGetMidX(layerRect), CGRectGetMidY(layerRect))]; 156 | 157 | [_capture setvideoScale]; 158 | 159 | // create a view, on which we attach the AV Preview layer 160 | CGRect frame = self.view.bounds; 161 | CGFloat toolbarHeight = [_toolbar frame].size.height; 162 | frame.size.height = frame.size.height - toolbarHeight; 163 | _cameraView = [[UIView alloc] initWithFrame:frame]; 164 | [[_cameraView layer] addSublayer:[_capture previewLayer]]; 165 | 166 | UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)]; 167 | [singleTap setNumberOfTapsRequired:1]; 168 | [_cameraView addGestureRecognizer:singleTap]; 169 | 170 | [self initFocusView]; 171 | 172 | NSString *str = @"姓名"; 173 | str = @""; 174 | UIFont *font = [UIFont systemFontOfSize:13]; 175 | CGSize size = [str sizeWithFont:font 176 | constrainedToSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT) 177 | lineBreakMode:NSLineBreakByWordWrapping]; 178 | 179 | nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(3, (3+size.height)*1, size.width, size.height)]; 180 | nameLabel.text = str; 181 | nameLabel.backgroundColor = [UIColor clearColor]; 182 | nameLabel.textColor =[UIColor greenColor]; 183 | nameLabel.font = [UIFont systemFontOfSize:13]; 184 | [_cameraView addSubview:nameLabel]; 185 | 186 | 187 | //str = @"性别"; 188 | size = [str sizeWithFont:font 189 | constrainedToSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT) 190 | lineBreakMode:NSLineBreakByWordWrapping]; 191 | genderLabel = [[UILabel alloc]initWithFrame:CGRectMake(3, (3+size.height)*2, size.width, size.height)]; 192 | genderLabel.text = str; 193 | genderLabel.backgroundColor = [UIColor clearColor]; 194 | genderLabel.textColor =[UIColor greenColor]; 195 | genderLabel.font = [UIFont systemFontOfSize:13]; 196 | [_cameraView addSubview:genderLabel]; 197 | 198 | 199 | //str = @"民族"; 200 | size = [str sizeWithFont:font 201 | constrainedToSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT) 202 | lineBreakMode:NSLineBreakByWordWrapping]; 203 | nationLabel = [[UILabel alloc]initWithFrame:CGRectMake(3, (3+size.height)*3, size.width, size.height)]; 204 | nationLabel.text = str; 205 | nationLabel.backgroundColor = [UIColor clearColor]; 206 | nationLabel.textColor =[UIColor greenColor]; 207 | nationLabel.font = [UIFont systemFontOfSize:13]; 208 | [_cameraView addSubview:nationLabel]; 209 | 210 | 211 | //str = @"地址"; 212 | size = [str sizeWithFont:font 213 | constrainedToSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT) 214 | lineBreakMode:NSLineBreakByWordWrapping]; 215 | addressLabel = [[UILabel alloc]initWithFrame:CGRectMake(3, (3+size.height)*4, size.width, size.height)]; 216 | addressLabel.text = str; 217 | addressLabel.backgroundColor = [UIColor clearColor]; 218 | addressLabel.textColor =[UIColor greenColor]; 219 | addressLabel.font = [UIFont systemFontOfSize:13]; 220 | [_cameraView addSubview:addressLabel]; 221 | 222 | 223 | 224 | //str = @"身份证号"; 225 | size = [str sizeWithFont:font 226 | constrainedToSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT) 227 | lineBreakMode:NSLineBreakByWordWrapping]; 228 | codeLabel = [[UILabel alloc]initWithFrame:CGRectMake(3, (3+size.height)*5, size.width, size.height)]; 229 | codeLabel.text = str; 230 | codeLabel.backgroundColor = [UIColor clearColor]; 231 | codeLabel.textColor =[UIColor greenColor]; 232 | codeLabel.font = [UIFont systemFontOfSize:13]; 233 | [_cameraView addSubview:codeLabel]; 234 | 235 | 236 | 237 | //str = @"签发机关"; 238 | size = [str sizeWithFont:font 239 | constrainedToSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT) 240 | lineBreakMode:NSLineBreakByWordWrapping]; 241 | issueLabel = [[UILabel alloc]initWithFrame:CGRectMake(3, (3+size.height)*6, size.width, size.height)]; 242 | issueLabel.text = str; 243 | issueLabel.backgroundColor = [UIColor clearColor]; 244 | issueLabel.textColor =[UIColor greenColor]; 245 | issueLabel.font = [UIFont systemFontOfSize:13]; 246 | [_cameraView addSubview:issueLabel]; 247 | 248 | 249 | //str = @"有效期"; 250 | size = [str sizeWithFont:font 251 | constrainedToSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT) 252 | lineBreakMode:NSLineBreakByWordWrapping]; 253 | validLabel = [[UILabel alloc]initWithFrame:CGRectMake(3, (3+size.height)*7, size.width, size.height)]; 254 | validLabel.text = str; 255 | validLabel.backgroundColor = [UIColor clearColor]; 256 | validLabel.textColor =[UIColor greenColor]; 257 | validLabel.font = [UIFont systemFontOfSize:13]; 258 | [_cameraView addSubview:validLabel]; 259 | 260 | 261 | // add the view we just created as a subview to the View Controller's view 262 | [self.view addSubview: _cameraView]; 263 | [self.view sendSubviewToBack:_cameraView]; 264 | 265 | // start ! 266 | [self performSelectorInBackground:@selector(startCapture) withObject:nil]; 267 | } 268 | 269 | -(void)initFocusView 270 | { 271 | _focusView = [[UIView alloc] init]; 272 | _focusView.frame = CGRectMake(0, 0, 80, 80); 273 | _focusView.backgroundColor = [UIColor clearColor]; 274 | _focusView.layer.borderColor = [UIColor whiteColor].CGColor; 275 | _focusView.layer.borderWidth = 1; 276 | _focusView.layer.masksToBounds = YES; 277 | _focusView.layer.cornerRadius = _focusView.frame.size.width/2; 278 | 279 | UIView *smallView = [[UIView alloc] init]; 280 | smallView.frame = CGRectMake(_focusView.frame.size.width/2 - 64/2, _focusView.frame.size.height/2 - 64/2, 64, 64); 281 | smallView.backgroundColor = [UIColor clearColor]; 282 | smallView.layer.borderColor = [UIColor whiteColor].CGColor; 283 | smallView.layer.borderWidth = 2; 284 | smallView.layer.masksToBounds = YES; 285 | smallView.layer.cornerRadius = smallView.frame.size.width/2; 286 | smallView.alpha = 0.7f; 287 | [_focusView addSubview:smallView]; 288 | } 289 | 290 | 291 | - (void)removeCapture 292 | { 293 | [_capture.captureSession stopRunning]; 294 | [_cameraView removeFromSuperview]; 295 | _capture = nil; 296 | _cameraView = nil; 297 | } 298 | 299 | - (void)startCapture 300 | { 301 | //@autoreleasepool 302 | { 303 | [[_capture captureSession] startRunning]; 304 | } 305 | } 306 | 307 | //单机 308 | - (void)singleTap:(UIGestureRecognizer*)gestureRecognizer 309 | { 310 | 311 | CGPoint point = [gestureRecognizer locationInView:_cameraView.superview]; 312 | 313 | NSLog(@"point = %f,%f",point.x,point.y); 314 | 315 | CGPoint focuspoint = CGPointMake(point.x/_cameraView.frame.size.width, point.y/_cameraView.frame.size.height); 316 | [_capture focusInPoint:focuspoint]; 317 | 318 | [self showFocusView:point]; 319 | } 320 | 321 | -(void)showFocusView:(CGPoint )point 322 | { 323 | [_focusView.layer removeAllAnimations]; 324 | [_focusView removeFromSuperview]; 325 | _focusView.center = point; 326 | _focusView.transform = CGAffineTransformMakeScale(0.8, 0.8); 327 | _focusView.alpha = 1; 328 | [_cameraView addSubview:_focusView]; 329 | 330 | [UIView animateWithDuration:0.52f 331 | delay:0.0 332 | usingSpringWithDamping:0.4f 333 | initialSpringVelocity:0.f 334 | options:UIViewAnimationOptionBeginFromCurrentState | 335 | UIViewAnimationOptionCurveEaseInOut | 336 | UIViewAnimationOptionOverrideInheritedDuration 337 | animations:^{ 338 | 339 | _focusView.transform = CGAffineTransformMakeScale(1, 1); 340 | 341 | } completion:^(BOOL finished) { 342 | 343 | if(finished) { 344 | [UIView animateWithDuration:0.52f 345 | delay:0.0 346 | usingSpringWithDamping:0.4f 347 | initialSpringVelocity:0.f 348 | options:UIViewAnimationOptionBeginFromCurrentState | 349 | UIViewAnimationOptionCurveEaseInOut | 350 | UIViewAnimationOptionOverrideInheritedDuration 351 | animations:^{ 352 | _focusView.alpha = 0; 353 | } completion:^(BOOL finished) { 354 | 355 | if(finished) { 356 | [_focusView removeFromSuperview]; 357 | } 358 | }]; 359 | } 360 | }]; 361 | } 362 | 363 | 364 | #pragma mark - Capture Delegates 365 | - (void)idCardRecognited:(IdInfo*)idInfo 366 | { 367 | dispatch_async(dispatch_get_main_queue(), ^(void) { 368 | if (idInfo.name != nil) 369 | { 370 | [nameLabel setText:[NSString stringWithFormat:@"姓名:%@", idInfo.name]]; 371 | CGSize size = [nameLabel.text sizeWithFont:nameLabel.font 372 | constrainedToSize:CGSizeMake(CGRectGetWidth(self.view.bounds), MAXFLOAT) 373 | lineBreakMode:NSLineBreakByWordWrapping]; 374 | [nameLabel setFrame:CGRectMake(3, (3+size.height)*1, size.width, size.height)]; 375 | } 376 | 377 | if (idInfo.gender != nil) 378 | { 379 | [genderLabel setText:[NSString stringWithFormat:@"性别:%@", idInfo.gender]]; 380 | CGSize size = [genderLabel.text sizeWithFont:nameLabel.font 381 | constrainedToSize:CGSizeMake(CGRectGetWidth(self.view.bounds), MAXFLOAT) 382 | lineBreakMode:NSLineBreakByWordWrapping]; 383 | [genderLabel setFrame:CGRectMake(3, (3+size.height)*2, size.width, size.height)]; 384 | } 385 | 386 | if (idInfo.nation != nil) 387 | { 388 | [nationLabel setText:[NSString stringWithFormat:@"民族:%@", idInfo.nation]]; 389 | CGSize size = [nationLabel.text sizeWithFont:nameLabel.font 390 | constrainedToSize:CGSizeMake(CGRectGetWidth(self.view.bounds), MAXFLOAT) 391 | lineBreakMode:NSLineBreakByWordWrapping]; 392 | [nationLabel setFrame:CGRectMake(3, (3+size.height)*3, size.width, size.height)]; 393 | } 394 | 395 | if (idInfo.address != nil) 396 | { 397 | [addressLabel setText:[NSString stringWithFormat:@"地址:%@", idInfo.address]]; 398 | CGSize size = [addressLabel.text sizeWithFont:nameLabel.font 399 | constrainedToSize:CGSizeMake(CGRectGetWidth(self.view.bounds), MAXFLOAT) 400 | lineBreakMode:NSLineBreakByWordWrapping]; 401 | [addressLabel setFrame:CGRectMake(3, (3+size.height)*4, size.width, size.height)]; 402 | } 403 | 404 | if (idInfo.code != nil) 405 | { 406 | [codeLabel setText:[NSString stringWithFormat:@"身份证号:%@", idInfo.code]]; 407 | CGSize size = [codeLabel.text sizeWithFont:nameLabel.font 408 | constrainedToSize:CGSizeMake(CGRectGetWidth(self.view.bounds), MAXFLOAT) 409 | lineBreakMode:NSLineBreakByWordWrapping]; 410 | [codeLabel setFrame:CGRectMake(3, (3+size.height)*5, size.width, size.height)]; 411 | } 412 | 413 | if (idInfo.issue != nil) 414 | { 415 | [issueLabel setText:[NSString stringWithFormat:@"签发机关:%@", idInfo.issue]]; 416 | CGSize size = [issueLabel.text sizeWithFont:issueLabel.font 417 | constrainedToSize:CGSizeMake(CGRectGetWidth(self.view.bounds), MAXFLOAT) 418 | lineBreakMode:NSLineBreakByWordWrapping]; 419 | [issueLabel setFrame:CGRectMake(3, (3+size.height)*6, size.width, size.height)]; 420 | } 421 | 422 | if (idInfo.valid != nil) 423 | { 424 | [validLabel setText:[NSString stringWithFormat:@"有效期:%@", idInfo.valid]]; 425 | CGSize size = [validLabel.text sizeWithFont:validLabel.font 426 | constrainedToSize:CGSizeMake(CGRectGetWidth(self.view.bounds), MAXFLOAT) 427 | lineBreakMode:NSLineBreakByWordWrapping]; 428 | [validLabel setFrame:CGRectMake(3, (3+size.height)*7, size.width, size.height)]; 429 | } 430 | }); 431 | 432 | //NSLog(@"%@", [idInfo toString]); 433 | [_capture.captureSession stopRunning]; 434 | 435 | /***** 436 | [self removeCapture]; 437 | [self dismissViewControllerAnimated: YES completion:nil]; 438 | 439 | if([self.delegate respondsToSelector:@selector(idCardRecognited:)]) 440 | { 441 | [self.delegate idCardRecognited:idInfo]; 442 | } 443 | *****/ 444 | } 445 | 446 | 447 | @end 448 | -------------------------------------------------------------------------------- /OCR-master/idcard/IdInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // IdInfo.h 3 | // idcard 4 | // 5 | // Created by hxg on 16-4-10. 6 | // Copyright (c) 2016年 林英伟. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface IdInfo : NSObject 12 | { 13 | } 14 | @property (nonatomic) int type; //1:正面 2:反面 15 | @property (retain, nonatomic) NSString *code; //身份证号 16 | @property (retain, nonatomic) NSString *name; //姓名 17 | @property (retain, nonatomic) NSString *gender; //性别 18 | @property (retain, nonatomic) NSString *nation; //民族 19 | @property (retain, nonatomic) NSString *address; //地址 20 | @property (retain, nonatomic) NSString *issue; //签发机关 21 | @property (retain, nonatomic) NSString *valid; //有效期 22 | 23 | -(NSString *)toString; 24 | -(BOOL)isOK; 25 | @end 26 | -------------------------------------------------------------------------------- /OCR-master/idcard/IdInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // IdInfo.m 3 | // idcard 4 | // 5 | // Created by hxg on 16-4-10. 6 | // Copyright (c) 2016年 林英伟. All rights reserved. 7 | // 8 | 9 | #import "IdInfo.h" 10 | 11 | @implementation IdInfo 12 | -(NSString *)toString 13 | { 14 | return [NSString stringWithFormat:@"身份证号:%@\n姓名:%@\n性别:%@\n民族:%@\n地址:%@", 15 | _code, _name, _gender, _nation, _address]; 16 | } 17 | 18 | -(BOOL)isOK 19 | { 20 | if (_code !=nil && _name!=nil && _gender!=nil && _nation!=nil && _address!=nil) 21 | { 22 | if (_code.length>0 && _name.length >0 && _gender.length>0 && _nation.length>0 && _address.length>0) 23 | { 24 | return true; 25 | } 26 | } 27 | else if (_issue !=nil && _valid!=nil) 28 | { 29 | if (_issue.length>0 && _valid.length >0) 30 | { 31 | return true; 32 | } 33 | } 34 | return false; 35 | } 36 | 37 | -(BOOL)isEqual:(IdInfo *)idInfo 38 | { 39 | if (idInfo == nil) 40 | return false; 41 | 42 | if ((_type == idInfo.type) && 43 | [_code isEqualToString:idInfo.code] && 44 | [_name isEqualToString:idInfo.name] && 45 | [_gender isEqualToString:idInfo.gender] && 46 | [_nation isEqualToString:idInfo.nation] && 47 | [_address isEqualToString:idInfo.address] && 48 | [_issue isEqualToString:idInfo.issue] && 49 | [_valid isEqualToString:idInfo.valid]) 50 | return true; 51 | 52 | return false; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /OCR-master/idcard/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "id.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "idiom" : "iphone", 11 | "size" : "29x29", 12 | "scale" : "3x" 13 | }, 14 | { 15 | "size" : "40x40", 16 | "idiom" : "iphone", 17 | "filename" : "id_80x80.png", 18 | "scale" : "2x" 19 | }, 20 | { 21 | "idiom" : "iphone", 22 | "size" : "40x40", 23 | "scale" : "3x" 24 | }, 25 | { 26 | "size" : "60x60", 27 | "idiom" : "iphone", 28 | "filename" : "id_120x120.png", 29 | "scale" : "2x" 30 | }, 31 | { 32 | "idiom" : "iphone", 33 | "size" : "60x60", 34 | "scale" : "3x" 35 | }, 36 | { 37 | "size" : "29x29", 38 | "idiom" : "ipad", 39 | "filename" : "id_29x29.png", 40 | "scale" : "1x" 41 | }, 42 | { 43 | "size" : "29x29", 44 | "idiom" : "ipad", 45 | "filename" : "id_58x58.png", 46 | "scale" : "2x" 47 | }, 48 | { 49 | "size" : "40x40", 50 | "idiom" : "ipad", 51 | "filename" : "id_40x40.png", 52 | "scale" : "1x" 53 | }, 54 | { 55 | "size" : "40x40", 56 | "idiom" : "ipad", 57 | "filename" : "id_80x80-1.png", 58 | "scale" : "2x" 59 | }, 60 | { 61 | "size" : "76x76", 62 | "idiom" : "ipad", 63 | "filename" : "id_76x76.png", 64 | "scale" : "1x" 65 | }, 66 | { 67 | "size" : "76x76", 68 | "idiom" : "ipad", 69 | "filename" : "id_152x152.png", 70 | "scale" : "2x" 71 | }, 72 | { 73 | "idiom" : "ipad", 74 | "size" : "83.5x83.5", 75 | "scale" : "2x" 76 | } 77 | ], 78 | "info" : { 79 | "version" : 1, 80 | "author" : "xcode" 81 | } 82 | } -------------------------------------------------------------------------------- /OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id.png -------------------------------------------------------------------------------- /OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_120x120.png -------------------------------------------------------------------------------- /OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_152x152.png -------------------------------------------------------------------------------- /OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_29x29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_29x29.png -------------------------------------------------------------------------------- /OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_40x40.png -------------------------------------------------------------------------------- /OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_58x58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_58x58.png -------------------------------------------------------------------------------- /OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_76x76.png -------------------------------------------------------------------------------- /OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_80x80-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_80x80-1.png -------------------------------------------------------------------------------- /OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_80x80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/idcard/Images.xcassets/AppIcon.appiconset/id_80x80.png -------------------------------------------------------------------------------- /OCR-master/idcard/Images.xcassets/LaunchImage.launchimage/1136.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/idcard/Images.xcassets/LaunchImage.launchimage/1136.png -------------------------------------------------------------------------------- /OCR-master/idcard/Images.xcassets/LaunchImage.launchimage/960.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/idcard/Images.xcassets/LaunchImage.launchimage/960.png -------------------------------------------------------------------------------- /OCR-master/idcard/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "filename" : "960.png", 7 | "extent" : "full-screen", 8 | "minimum-system-version" : "7.0", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "extent" : "full-screen", 13 | "idiom" : "iphone", 14 | "subtype" : "retina4", 15 | "filename" : "1136.png", 16 | "minimum-system-version" : "7.0", 17 | "orientation" : "portrait", 18 | "scale" : "2x" 19 | }, 20 | { 21 | "orientation" : "portrait", 22 | "idiom" : "ipad", 23 | "extent" : "full-screen", 24 | "minimum-system-version" : "7.0", 25 | "scale" : "1x" 26 | }, 27 | { 28 | "orientation" : "landscape", 29 | "idiom" : "ipad", 30 | "extent" : "full-screen", 31 | "minimum-system-version" : "7.0", 32 | "scale" : "1x" 33 | }, 34 | { 35 | "orientation" : "portrait", 36 | "idiom" : "ipad", 37 | "extent" : "full-screen", 38 | "minimum-system-version" : "7.0", 39 | "scale" : "2x" 40 | }, 41 | { 42 | "orientation" : "landscape", 43 | "idiom" : "ipad", 44 | "extent" : "full-screen", 45 | "minimum-system-version" : "7.0", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /OCR-master/idcard/QuartzHelpLibrary.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #pragma mark - Invaliables 5 | 6 | typedef enum { 7 | QH_PIXEL_GRAYSCALE = 0, 8 | QH_PIXEL_COLOR = 1 << 0, 9 | QH_PIXEL_ANYCOLOR = 1 << 1, 10 | }QH_PIXEL_TYPE; 11 | 12 | typedef enum { 13 | QH_BYTES_PER_PIXEL_UNKNOWN = 0, 14 | QH_BYTES_PER_PIXEL_8BIT = 1, 15 | QH_BYTES_PER_PIXEL_16BIT = 2, 16 | QH_BYTES_PER_PIXEL_24BIT = 3, 17 | QH_BYTES_PER_PIXEL_32BIT = 4, 18 | }QH_BYTES_PER_PIXEL; 19 | 20 | #define QH_DEFAULT_ALPHA_VALUE 0xff 21 | 22 | #define QH_DEFAULT_JPG_QUALITY 1.0 23 | 24 | #pragma mark - UIImage category 25 | 26 | @interface UIImage(QuartzHelpLibrary) 27 | - (NSData*)PNGRepresentaion; 28 | - (NSData*)JPEGRepresentaion; 29 | - (NSData*)JPEGRepresentaionWithCompressionQuality:(float)compressionQuality; 30 | - (UIImage*)getRotatedImage; 31 | - (UIImage*)getRotatedImageWithResizing:(float)scale; 32 | - (CGImageRef)createCGImageRotated; 33 | - (CGImageRef)createCGImageRotatedWithResizing:(float)scale; 34 | @end 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | #pragma mark - Load image file 41 | 42 | CGImageRef CGImageCreateWithPNGorJPEGFilePath(CFStringRef filePath); 43 | 44 | #pragma mark - Dump CGImage information 45 | 46 | void CGImageDumpImageInformation(CGImageRef imageRef); 47 | 48 | #pragma mark - Read pixel from CGImage 49 | 50 | void CGCreatePixelBufferWithImage(CGImageRef imageRef, unsigned char **pixel, int *width, int *height, int *bytesPerPixel, QH_PIXEL_TYPE pType); 51 | 52 | #pragma mark - Creating CGImage 53 | 54 | CGImageRef CGImageCreateWithPixelBuffer(unsigned char *pixel, int width, int height, int bytesPerPixel, QH_PIXEL_TYPE target_pType); 55 | 56 | #pragma mark - Convert CGImage to image file binary 57 | 58 | NSData* CGImageGetPNGPresentation(CGImageRef imageRef); 59 | NSData* CGImageGetJPEGPresentation(CGImageRef imageRef); 60 | 61 | #pragma mark - Resize 62 | 63 | CGImageRef CGImageCreateWithResizing(CGImageRef imageRef, float scale); 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif -------------------------------------------------------------------------------- /OCR-master/idcard/QuartzHelpLibrary.m: -------------------------------------------------------------------------------- 1 | #import "QuartzHelpLibrary.h" 2 | 3 | #pragma mark - Declare private functions 4 | 5 | void _CGImageDumpImageAttribute(CGImageRef imageRef); 6 | void _CGImageDumpAlphaInformation(CGImageRef imageRef); 7 | void _CGImageDumpBitmapInformation(CGImageRef imageRef); 8 | 9 | int _getYFromRGB(int r, int g, int b); 10 | 11 | void _CGCreate8bitPixelBufferWithImage(CGImageRef imageRef, unsigned char **pixel, int *width, int *height, int *bytesPerPixel, QH_PIXEL_TYPE pType); 12 | void _CGCreate24bitPixelBufferWithImage(CGImageRef imageRef, unsigned char **pixel, int *width, int *height, int *bytesPerPixel, QH_PIXEL_TYPE pType); 13 | void _CGCreate32bitPixelBufferWithImage(CGImageRef imageRef, unsigned char **pixel, int *width, int *height, int *bytesPerPixel, QH_PIXEL_TYPE pType); 14 | 15 | #pragma mark - Load image file 16 | 17 | CGImageRef CGImageCreateWithPNGorJPEGFilePath(CFStringRef filePath) { 18 | CGImageRef outputImage = NULL; 19 | 20 | CGDataProviderRef providerRef = CGDataProviderCreateWithFilename([(__bridge NSString*)filePath UTF8String]); 21 | 22 | if (outputImage == NULL) 23 | outputImage = CGImageCreateWithPNGDataProvider(providerRef, NULL, NO, 0); 24 | 25 | if (outputImage == NULL) 26 | outputImage = CGImageCreateWithJPEGDataProvider(providerRef, NULL, NO, 0); 27 | 28 | CGDataProviderRelease(providerRef); 29 | 30 | return outputImage; 31 | } 32 | 33 | #pragma mark - 34 | #pragma mark Dump CGImage information 35 | 36 | void _CGImageDumpImageAttribute(CGImageRef imageRef) { 37 | size_t width = CGImageGetWidth(imageRef); 38 | size_t height = CGImageGetHeight(imageRef); 39 | size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef); 40 | size_t bitsPerPixel = CGImageGetBitsPerPixel(imageRef); 41 | size_t bytesPerRow = CGImageGetBytesPerRow(imageRef); 42 | 43 | printf("width = %d\n", (int)width); 44 | printf("height = %d\n", (int)height); 45 | printf("bits per component = %d\n", (int)bitsPerComponent); 46 | printf("bits per pixel = %d\n", (int)bitsPerPixel); 47 | printf("bytes per pixel = %d\n", (int)bitsPerPixel/8); 48 | printf("bytes per row = %d\n", (int)bytesPerRow); 49 | } 50 | 51 | void _CGImageDumpAlphaInformation(CGImageRef imageRef) { 52 | CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef); 53 | // alpha information 54 | switch(alphaInfo) { 55 | case kCGImageAlphaNone: 56 | printf("Alpha Info = kCGImageAlphaNone\n"); 57 | break; 58 | case kCGImageAlphaPremultipliedLast: 59 | printf("Alpha Info = kCGImageAlphaPremultipliedLast\n"); 60 | break; 61 | case kCGImageAlphaPremultipliedFirst: 62 | printf("Alpha Info = kCGImageAlphaPremultipliedFirst\n"); 63 | break; 64 | case kCGImageAlphaLast: 65 | printf("Alpha Info = kCGImageAlphaLast\n"); 66 | break; 67 | case kCGImageAlphaFirst: 68 | printf("Alpha Info = kCGImageAlphaFirst\n"); 69 | break; 70 | case kCGImageAlphaNoneSkipLast: 71 | printf("Alpha Info = kCGImageAlphaNoneSkipLast\n"); 72 | break; 73 | case kCGImageAlphaNoneSkipFirst: 74 | printf("Alpha Info = kCGImageAlphaNoneSkipFirst\n"); 75 | break; 76 | default: 77 | printf("Alpha Info = Error unknown\n"); 78 | break; 79 | } 80 | } 81 | 82 | void _CGImageDumpBitmapInformation(CGImageRef imageRef) { 83 | CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); 84 | CGBitmapInfo byteOrderInfo = (bitmapInfo & kCGBitmapByteOrderMask); 85 | 86 | // special case 87 | if (bitmapInfo == kCGBitmapFloatComponents) { 88 | printf("Bitmap Info = kCGBitmapFloatComponents\n"); 89 | printf("Alpha Info = ?\n"); 90 | return; 91 | } 92 | 93 | // bitmap information 94 | switch(byteOrderInfo) { 95 | case kCGBitmapByteOrderMask: 96 | printf("Bitmap Info = kCGBitmapByteOrderMask\n"); 97 | break; 98 | case kCGBitmapByteOrderDefault: 99 | printf("Bitmap Info = kCGBitmapByteOrderDefault\n"); 100 | break; 101 | case kCGBitmapByteOrder16Little: 102 | printf("Bitmap Info = kCGBitmapByteOrder16Little\n"); 103 | break; 104 | case kCGBitmapByteOrder32Little: 105 | printf("Bitmap Info = kCGBitmapByteOrder32Little\n"); 106 | break; 107 | case kCGBitmapByteOrder16Big: 108 | printf("Bitmap Info = kCGBitmapByteOrder16Big\n"); 109 | break; 110 | case kCGBitmapByteOrder32Big: 111 | printf("Bitmap Info = kCGBitmapByteOrder32Big\n"); 112 | break; 113 | default: 114 | printf("Bitmap Info = Error unknown\n"); 115 | break; 116 | } 117 | } 118 | 119 | void CGImageDumpImageInformation(CGImageRef imageRef) { 120 | _CGImageDumpImageAttribute(imageRef); 121 | _CGImageDumpAlphaInformation(imageRef); 122 | _CGImageDumpBitmapInformation(imageRef); 123 | } 124 | 125 | #pragma mark - Read pixel from CGImage 126 | 127 | int _getYFromRGB(int r, int g, int b) { 128 | int y = 129 | ( ( 306 * (int)r + 512 ) >> 10 ) 130 | + ( ( 601 * (int)g + 512 ) >> 10 ) 131 | + ( ( 117 * (int)b + 512 ) >> 10 ); 132 | if ( y < 0x00 ) y = 0x00; 133 | if ( y > 0xFF ) y = 0xFF; 134 | return y; 135 | } 136 | 137 | void _CGCreate8bitPixelBufferWithImage(CGImageRef imageRef, unsigned char **pixel, int *width, int *height, int *bytesPerPixel, QH_PIXEL_TYPE pType) { 138 | CGImageAlphaInfo bitmapAlphaInfo = CGImageGetBitmapInfo(imageRef) & kCGBitmapAlphaInfoMask; 139 | size_t inputImageBytesPerPixel = CGImageGetBitsPerPixel(imageRef) / 8; 140 | 141 | // save image info 142 | *width = CGImageGetWidth(imageRef); 143 | *height = CGImageGetHeight(imageRef); 144 | *pixel = (unsigned char*)malloc(sizeof(unsigned char) * (*width) * (*height)); 145 | *bytesPerPixel = 1; 146 | 147 | // source image data 148 | CGDataProviderRef inputImageProvider = CGImageGetDataProvider(imageRef); 149 | CFDataRef data = CGDataProviderCopyData(inputImageProvider); 150 | unsigned char *sourceImagePixelData = (unsigned char *) CFDataGetBytePtr(data); 151 | size_t bytesPerRowSourceImage = CGImageGetBytesPerRow(imageRef); 152 | size_t bytesPerRowOutputImage = *width * QH_BYTES_PER_PIXEL_8BIT; 153 | CGBitmapInfo byteOrderInfo = (CGImageGetBitmapInfo(imageRef) & kCGBitmapByteOrderMask); 154 | 155 | switch(inputImageBytesPerPixel) { 156 | case QH_BYTES_PER_PIXEL_8BIT: 157 | { 158 | // open color table 159 | CGColorSpaceRef space = CGImageGetColorSpace(imageRef); 160 | 161 | if (CGColorSpaceGetModel(space) == kCGColorSpaceModelIndexed) { 162 | int tableCount = CGColorSpaceGetColorTableCount(space); 163 | unsigned char* table = (unsigned char* )malloc(tableCount * 3 * sizeof(unsigned char)); 164 | CGColorSpaceGetColorTable(space, table); 165 | 166 | for (int y = 0; y < *height; y++) { 167 | for (int x = 0; x < *width; x++) { 168 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 169 | int index = sourceImagePixelData[offset]; 170 | 171 | int k = _getYFromRGB(table[index * 3 + 0], table[index * 3 + 1], table[index * 3 + 2]); 172 | 173 | (*pixel)[y * bytesPerRowOutputImage + x] = k; 174 | } 175 | } 176 | free(table); 177 | } 178 | else { 179 | for (int y = 0; y < *height; y++) { 180 | for (int x = 0; x < *width; x++) { 181 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 182 | (*pixel)[y * bytesPerRowOutputImage + x] = sourceImagePixelData[offset]; 183 | } 184 | } 185 | } 186 | } 187 | break; 188 | case QH_BYTES_PER_PIXEL_16BIT: 189 | // first alpha 190 | if (bitmapAlphaInfo == kCGImageAlphaFirst || bitmapAlphaInfo == kCGImageAlphaNoneSkipFirst || bitmapAlphaInfo == kCGImageAlphaPremultipliedFirst) { 191 | if (byteOrderInfo == kCGBitmapByteOrder16Little || byteOrderInfo == kCGBitmapByteOrder16Host || byteOrderInfo == kCGBitmapByteOrderDefault) { 192 | // little endian AY 193 | for (int y = 0; y < *height; y++) { 194 | for (int x = 0; x < *width; x++) { 195 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel + 1; 196 | (*pixel)[y * bytesPerRowOutputImage + x] = sourceImagePixelData[offset]; 197 | } 198 | } 199 | } 200 | else if (byteOrderInfo == kCGBitmapByteOrder16Big) { 201 | // big endian YA 202 | for (int y = 0; y < *height; y++) { 203 | for (int x = 0; x < *width; x++) { 204 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel + 0; 205 | (*pixel)[y * bytesPerRowOutputImage + x] = sourceImagePixelData[offset]; 206 | } 207 | } 208 | } 209 | else 210 | goto LOAD_EXCEPTION; 211 | } 212 | // last alpha 213 | else if (bitmapAlphaInfo == kCGImageAlphaLast || bitmapAlphaInfo == kCGImageAlphaNoneSkipLast || bitmapAlphaInfo == kCGImageAlphaPremultipliedLast) { 214 | if (byteOrderInfo == kCGBitmapByteOrder16Little || byteOrderInfo == kCGBitmapByteOrder16Host || byteOrderInfo == kCGBitmapByteOrderDefault) { 215 | // little endian YA 216 | for (int y = 0; y < *height; y++) { 217 | for (int x = 0; x < *width; x++) { 218 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel + 0; 219 | (*pixel)[y * bytesPerRowOutputImage + x] = sourceImagePixelData[offset]; 220 | } 221 | } 222 | } 223 | else if (byteOrderInfo == kCGBitmapByteOrder16Big) { 224 | // big endian AY 225 | for (int y = 0; y < *height; y++) { 226 | for (int x = 0; x < *width; x++) { 227 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel + 1; 228 | (*pixel)[y * bytesPerRowOutputImage + x] = sourceImagePixelData[offset]; 229 | } 230 | } 231 | } 232 | else 233 | goto LOAD_EXCEPTION; 234 | } 235 | break; 236 | case QH_BYTES_PER_PIXEL_24BIT: 237 | // maybe, there are not any following caces. 238 | // little endian? 239 | for (int y = 0; y < *height; y++) { 240 | for (int x = 0; x < *width; x++) { 241 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 242 | int k = _getYFromRGB(sourceImagePixelData[offset + 0], sourceImagePixelData[offset + 1], sourceImagePixelData[offset + 2]); 243 | (*pixel)[y * bytesPerRowOutputImage + x] = k; 244 | } 245 | } 246 | break; 247 | case QH_BYTES_PER_PIXEL_32BIT: 248 | // first alpha 249 | if (bitmapAlphaInfo == kCGImageAlphaFirst || bitmapAlphaInfo == kCGImageAlphaNoneSkipFirst || bitmapAlphaInfo == kCGImageAlphaPremultipliedFirst) { 250 | if (byteOrderInfo == kCGBitmapByteOrder32Little || byteOrderInfo == kCGBitmapByteOrder32Host || byteOrderInfo == kCGBitmapByteOrderDefault) { 251 | // little endian ARGB 252 | for (int y = 0; y < *height; y++) { 253 | for (int x = 0; x < *width; x++) { 254 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 255 | int k = _getYFromRGB(sourceImagePixelData[offset + 1], sourceImagePixelData[offset + 2], sourceImagePixelData[offset + 3]); 256 | (*pixel)[y * bytesPerRowOutputImage + x] = k; 257 | } 258 | } 259 | } 260 | else if (byteOrderInfo == kCGBitmapByteOrder32Big) { 261 | // big endian ABGR 262 | for (int y = 0; y < *height; y++) { 263 | for (int x = 0; x < *width; x++) { 264 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 265 | int k = _getYFromRGB(sourceImagePixelData[offset + 3], sourceImagePixelData[offset + 2], sourceImagePixelData[offset + 1]); 266 | (*pixel)[y * bytesPerRowOutputImage + x] = k; 267 | } 268 | } 269 | } 270 | else 271 | goto LOAD_EXCEPTION; 272 | } 273 | 274 | // last alpha 275 | else if (bitmapAlphaInfo == kCGImageAlphaLast || bitmapAlphaInfo == kCGImageAlphaNoneSkipLast || bitmapAlphaInfo == kCGImageAlphaPremultipliedLast) { 276 | if (byteOrderInfo == kCGBitmapByteOrder32Little || byteOrderInfo == kCGBitmapByteOrder32Host || byteOrderInfo == kCGBitmapByteOrderDefault) { 277 | // little endian RGBA 278 | for (int y = 0; y < *height; y++) { 279 | for (int x = 0; x < *width; x++) { 280 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 281 | int k = _getYFromRGB(sourceImagePixelData[offset + 0], sourceImagePixelData[offset + 1], sourceImagePixelData[offset + 2]); 282 | (*pixel)[y * bytesPerRowOutputImage + x] = k; 283 | } 284 | } 285 | } 286 | else if (byteOrderInfo == kCGBitmapByteOrder32Big) { 287 | // big endian BGRA 288 | for (int y = 0; y < *height; y++) { 289 | for (int x = 0; x < *width; x++) { 290 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 291 | 292 | int k = _getYFromRGB(sourceImagePixelData[offset + 2], sourceImagePixelData[offset + 1], sourceImagePixelData[offset]); 293 | (*pixel)[y * bytesPerRowOutputImage + x] = k; 294 | } 295 | } 296 | } 297 | else 298 | goto LOAD_EXCEPTION; 299 | } 300 | break; 301 | default: 302 | goto LOAD_EXCEPTION; 303 | break; 304 | } 305 | CFRelease(data); 306 | return; 307 | LOAD_EXCEPTION: 308 | printf("Error\n"); 309 | free(*pixel); 310 | *width = 0; 311 | *height = 0; 312 | *bytesPerPixel = 0; 313 | *pixel = NULL; 314 | CFRelease(data); 315 | return; 316 | } 317 | 318 | void _CGCreate24bitPixelBufferWithImage(CGImageRef imageRef, unsigned char **pixel, int *width, int *height, int *bytesPerPixel, QH_PIXEL_TYPE pType) { 319 | CGImageAlphaInfo bitmapAlphaInfo = CGImageGetBitmapInfo(imageRef) & kCGBitmapAlphaInfoMask; 320 | size_t inputImageBytesPerPixel = CGImageGetBitsPerPixel(imageRef) / 8; 321 | 322 | // save image info 323 | *width = CGImageGetWidth(imageRef); 324 | *height = CGImageGetHeight(imageRef); 325 | *bytesPerPixel = QH_BYTES_PER_PIXEL_24BIT; 326 | *pixel = (unsigned char*)malloc(sizeof(unsigned char) * (*width) * (*height) * (*bytesPerPixel)); 327 | 328 | // source image data 329 | CGDataProviderRef inputImageProvider = CGImageGetDataProvider(imageRef); 330 | CFDataRef data = CGDataProviderCopyData(inputImageProvider); 331 | unsigned char *sourceImagePixelData = (unsigned char *) CFDataGetBytePtr(data); 332 | size_t bytesPerRowSourceImage = CGImageGetBytesPerRow(imageRef); 333 | size_t bytesPerRowOutputImage = *width * (*bytesPerPixel); 334 | CGBitmapInfo byteOrderInfo = (CGImageGetBitmapInfo(imageRef) & kCGBitmapByteOrderMask); 335 | 336 | switch(inputImageBytesPerPixel) { 337 | case QH_BYTES_PER_PIXEL_8BIT: 338 | { 339 | // open color table 340 | CGColorSpaceRef space = CGImageGetColorSpace(imageRef); 341 | 342 | if (CGColorSpaceGetModel(space) != kCGColorSpaceModelIndexed) { 343 | goto LOAD_EXCEPTION; 344 | } 345 | 346 | int tableCount = CGColorSpaceGetColorTableCount(space); 347 | unsigned char* table = (unsigned char* )malloc(tableCount * (*bytesPerPixel) * sizeof(unsigned char)); 348 | CGColorSpaceGetColorTable(space, table); 349 | 350 | for (int y = 0; y < *height; y++) { 351 | for (int x = 0; x < *width; x++) { 352 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 353 | int index = sourceImagePixelData[offset]; 354 | 355 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = table[index * 3 + 0]; 356 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = table[index * 3 + 1]; 357 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = table[index * 3 + 2]; 358 | } 359 | } 360 | free(table); 361 | } 362 | break; 363 | case QH_BYTES_PER_PIXEL_16BIT: 364 | // first alpha 365 | if (bitmapAlphaInfo == kCGImageAlphaFirst || bitmapAlphaInfo == kCGImageAlphaNoneSkipFirst || bitmapAlphaInfo == kCGImageAlphaPremultipliedFirst) { 366 | if (byteOrderInfo == kCGBitmapByteOrder16Little || byteOrderInfo == kCGBitmapByteOrder16Host || byteOrderInfo == kCGBitmapByteOrderDefault) { 367 | // little endian AY 368 | for (int y = 0; y < *height; y++) { 369 | for (int x = 0; x < *width; x++) { 370 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel + 1; 371 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset]; 372 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset]; 373 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset]; 374 | } 375 | } 376 | } 377 | else if (byteOrderInfo == kCGBitmapByteOrder16Big) { 378 | // big endian YA 379 | for (int y = 0; y < *height; y++) { 380 | for (int x = 0; x < *width; x++) { 381 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel + 0; 382 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset]; 383 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset]; 384 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset]; 385 | } 386 | } 387 | } 388 | else 389 | goto LOAD_EXCEPTION; 390 | } 391 | // last alpha 392 | else if (bitmapAlphaInfo == kCGImageAlphaLast || bitmapAlphaInfo == kCGImageAlphaNoneSkipLast || bitmapAlphaInfo == kCGImageAlphaPremultipliedLast) { 393 | if (byteOrderInfo == kCGBitmapByteOrder16Little || byteOrderInfo == kCGBitmapByteOrder16Host || byteOrderInfo == kCGBitmapByteOrderDefault) { 394 | // little endian YA 395 | for (int y = 0; y < *height; y++) { 396 | for (int x = 0; x < *width; x++) { 397 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel + 0; 398 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset]; 399 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset]; 400 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset]; 401 | } 402 | } 403 | } 404 | else if (byteOrderInfo == kCGBitmapByteOrder16Big) { 405 | // big endian AY 406 | for (int y = 0; y < *height; y++) { 407 | for (int x = 0; x < *width; x++) { 408 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel + 1; 409 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset]; 410 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset]; 411 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset]; 412 | } 413 | } 414 | } 415 | else 416 | goto LOAD_EXCEPTION; 417 | } 418 | break; 419 | case QH_BYTES_PER_PIXEL_24BIT: 420 | // maybe, there are not any following caces. 421 | // little endian? 422 | for (int y = 0; y < *height; y++) { 423 | for (int x = 0; x < *width; x++) { 424 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 425 | 426 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset + 0]; 427 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset + 1]; 428 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset + 2]; 429 | } 430 | } 431 | break; 432 | case QH_BYTES_PER_PIXEL_32BIT: 433 | // first alpha 434 | if (bitmapAlphaInfo == kCGImageAlphaFirst || bitmapAlphaInfo == kCGImageAlphaNoneSkipFirst || bitmapAlphaInfo == kCGImageAlphaPremultipliedFirst) { 435 | if (byteOrderInfo == kCGBitmapByteOrder32Little || byteOrderInfo == kCGBitmapByteOrder32Host || byteOrderInfo == kCGBitmapByteOrderDefault) { 436 | // little endian BGRA 437 | for (int y = 0; y < *height; y++) { 438 | for (int x = 0; x < *width; x++) { 439 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 440 | 441 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset + 2]; 442 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset + 1]; 443 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset + 0]; 444 | } 445 | } 446 | } 447 | else if (byteOrderInfo == kCGBitmapByteOrder32Big) { 448 | // big endian ARGB 449 | for (int y = 0; y < *height; y++) { 450 | for (int x = 0; x < *width; x++) { 451 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 452 | 453 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset + 1]; 454 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset + 2]; 455 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset + 3]; 456 | } 457 | } 458 | } 459 | else 460 | goto LOAD_EXCEPTION; 461 | } 462 | 463 | // last alpha 464 | else if (bitmapAlphaInfo == kCGImageAlphaLast || bitmapAlphaInfo == kCGImageAlphaNoneSkipLast || bitmapAlphaInfo == kCGImageAlphaPremultipliedLast) { 465 | if (byteOrderInfo == kCGBitmapByteOrder32Little || byteOrderInfo == kCGBitmapByteOrder32Host) { 466 | // little endian RGBA 467 | for (int y = 0; y < *height; y++) { 468 | for (int x = 0; x < *width; x++) { 469 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 470 | 471 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset + 3]; 472 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset + 2]; 473 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset + 1]; 474 | } 475 | } 476 | } 477 | else if (byteOrderInfo == kCGBitmapByteOrder32Big || byteOrderInfo == kCGBitmapByteOrderDefault) { 478 | // big endian BGRA 479 | for (int y = 0; y < *height; y++) { 480 | for (int x = 0; x < *width; x++) { 481 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 482 | 483 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset + 0]; 484 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset + 1]; 485 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset + 2]; 486 | } 487 | } 488 | } 489 | else 490 | goto LOAD_EXCEPTION; 491 | } 492 | break; 493 | default: 494 | goto LOAD_EXCEPTION; 495 | break; 496 | } 497 | CFRelease(data); 498 | return; 499 | LOAD_EXCEPTION: 500 | printf("Error\n"); 501 | free(*pixel); 502 | *width = 0; 503 | *height = 0; 504 | *bytesPerPixel = 0; 505 | *pixel = NULL; 506 | CFRelease(data); 507 | return; 508 | } 509 | 510 | void _CGCreate32bitPixelBufferWithImage(CGImageRef imageRef, unsigned char **pixel, int *width, int *height, int *bytesPerPixel, QH_PIXEL_TYPE pType) { 511 | CGImageAlphaInfo bitmapAlphaInfo = CGImageGetBitmapInfo(imageRef) & kCGBitmapAlphaInfoMask; 512 | size_t inputImageBytesPerPixel = CGImageGetBitsPerPixel(imageRef) / 8; 513 | 514 | // save image info 515 | *width = CGImageGetWidth(imageRef); 516 | *height = CGImageGetHeight(imageRef); 517 | *bytesPerPixel = QH_BYTES_PER_PIXEL_32BIT; 518 | *pixel = (unsigned char*)malloc(sizeof(unsigned char) * (*width) * (*height) * (*bytesPerPixel)); 519 | 520 | // source image data 521 | CGDataProviderRef inputImageProvider = CGImageGetDataProvider(imageRef); 522 | CFDataRef data = CGDataProviderCopyData(inputImageProvider); 523 | unsigned char *sourceImagePixelData = (unsigned char *) CFDataGetBytePtr(data); 524 | size_t bytesPerRowSourceImage = CGImageGetBytesPerRow(imageRef); 525 | size_t bytesPerRowOutputImage = *width * (*bytesPerPixel); 526 | CGBitmapInfo byteOrderInfo = (CGImageGetBitmapInfo(imageRef) & kCGBitmapByteOrderMask); 527 | 528 | switch(inputImageBytesPerPixel) { 529 | case QH_BYTES_PER_PIXEL_8BIT: 530 | { 531 | // open color table 532 | CGColorSpaceRef space = CGImageGetColorSpace(imageRef); 533 | 534 | if (CGColorSpaceGetModel(space) != kCGColorSpaceModelIndexed) { 535 | goto LOAD_EXCEPTION; 536 | } 537 | 538 | int tableCount = CGColorSpaceGetColorTableCount(space); 539 | unsigned char* table = (unsigned char* )malloc(tableCount * (*bytesPerPixel) * sizeof(unsigned char)); 540 | CGColorSpaceGetColorTable(space, table); 541 | 542 | for (int y = 0; y < *height; y++) { 543 | for (int x = 0; x < *width; x++) { 544 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 545 | int index = sourceImagePixelData[offset]; 546 | 547 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = table[index * 3 + 0]; 548 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = table[index * 3 + 1]; 549 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = table[index * 3 + 2]; 550 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 3] = QH_DEFAULT_ALPHA_VALUE; 551 | } 552 | } 553 | free(table); 554 | } 555 | break; 556 | case QH_BYTES_PER_PIXEL_16BIT: 557 | // first alpha 558 | if (bitmapAlphaInfo == kCGImageAlphaFirst || bitmapAlphaInfo == kCGImageAlphaNoneSkipFirst || bitmapAlphaInfo == kCGImageAlphaPremultipliedFirst) { 559 | if (byteOrderInfo == kCGBitmapByteOrder16Little || byteOrderInfo == kCGBitmapByteOrder16Host || byteOrderInfo == kCGBitmapByteOrderDefault) { 560 | // little endian AY 561 | for (int y = 0; y < *height; y++) { 562 | for (int x = 0; x < *width; x++) { 563 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel + 1; 564 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset]; 565 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset]; 566 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset]; 567 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 3] = sourceImagePixelData[offset - 1]; 568 | } 569 | } 570 | } 571 | else if (byteOrderInfo == kCGBitmapByteOrder16Big) { 572 | // big endian YA 573 | for (int y = 0; y < *height; y++) { 574 | for (int x = 0; x < *width; x++) { 575 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel + 0; 576 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset]; 577 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset]; 578 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset]; 579 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 3] = sourceImagePixelData[offset + 1]; 580 | } 581 | } 582 | } 583 | else 584 | goto LOAD_EXCEPTION; 585 | } 586 | // last alpha 587 | else if (bitmapAlphaInfo == kCGImageAlphaLast || bitmapAlphaInfo == kCGImageAlphaNoneSkipLast || bitmapAlphaInfo == kCGImageAlphaPremultipliedLast) { 588 | if (byteOrderInfo == kCGBitmapByteOrder16Little || byteOrderInfo == kCGBitmapByteOrder16Host || byteOrderInfo == kCGBitmapByteOrderDefault) { 589 | // little endian YA 590 | for (int y = 0; y < *height; y++) { 591 | for (int x = 0; x < *width; x++) { 592 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel + 0; 593 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset]; 594 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset]; 595 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset]; 596 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 3] = sourceImagePixelData[offset + 1]; 597 | } 598 | } 599 | } 600 | else if (byteOrderInfo == kCGBitmapByteOrder16Big) { 601 | // big endian AY 602 | for (int y = 0; y < *height; y++) { 603 | for (int x = 0; x < *width; x++) { 604 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel + 1; 605 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset]; 606 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset]; 607 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset]; 608 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 3] = sourceImagePixelData[offset - 1]; 609 | } 610 | } 611 | } 612 | else 613 | goto LOAD_EXCEPTION; 614 | } 615 | break; 616 | case QH_BYTES_PER_PIXEL_24BIT: 617 | // maybe, there are not any following caces. 618 | // little endian? 619 | for (int y = 0; y < *height; y++) { 620 | for (int x = 0; x < *width; x++) { 621 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 622 | 623 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset + 0]; 624 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset + 1]; 625 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset + 2]; 626 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 3] = QH_DEFAULT_ALPHA_VALUE; 627 | } 628 | } 629 | break; 630 | case QH_BYTES_PER_PIXEL_32BIT: 631 | // first alpha 632 | if (bitmapAlphaInfo == kCGImageAlphaFirst || bitmapAlphaInfo == kCGImageAlphaNoneSkipFirst || bitmapAlphaInfo == kCGImageAlphaPremultipliedFirst) { 633 | if (byteOrderInfo == kCGBitmapByteOrder32Little || byteOrderInfo == kCGBitmapByteOrder32Host || byteOrderInfo == kCGBitmapByteOrderDefault) { 634 | // little endian BGRA 635 | for (int y = 0; y < *height; y++) { 636 | for (int x = 0; x < *width; x++) { 637 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 638 | 639 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset + 1]; 640 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset + 2]; 641 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset + 3]; 642 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 3] = sourceImagePixelData[offset + 0]; 643 | } 644 | } 645 | } 646 | else if (byteOrderInfo == kCGBitmapByteOrder32Big) { 647 | // big endian ARGB 648 | for (int y = 0; y < *height; y++) { 649 | for (int x = 0; x < *width; x++) { 650 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 651 | 652 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset + 2]; 653 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset + 1]; 654 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset + 0]; 655 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 3] = sourceImagePixelData[offset + 3]; 656 | } 657 | } 658 | } 659 | else 660 | goto LOAD_EXCEPTION; 661 | } 662 | 663 | // last alpha 664 | else if (bitmapAlphaInfo == kCGImageAlphaLast || bitmapAlphaInfo == kCGImageAlphaNoneSkipLast || bitmapAlphaInfo == kCGImageAlphaPremultipliedLast) { 665 | if (byteOrderInfo == kCGBitmapByteOrder32Little || byteOrderInfo == kCGBitmapByteOrder32Host || byteOrderInfo == kCGBitmapByteOrderDefault) { 666 | // little endian RGBA 667 | for (int y = 0; y < *height; y++) { 668 | for (int x = 0; x < *width; x++) { 669 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 670 | 671 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset + 0]; 672 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset + 1]; 673 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset + 2]; 674 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 3] = sourceImagePixelData[offset + 3]; 675 | } 676 | } 677 | } 678 | else if (byteOrderInfo == kCGBitmapByteOrder32Big) { 679 | // big endian -> BGRA 680 | for (int y = 0; y < *height; y++) { 681 | for (int x = 0; x < *width; x++) { 682 | int offset = y * bytesPerRowSourceImage + x * inputImageBytesPerPixel; 683 | 684 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 0] = sourceImagePixelData[offset + 2]; 685 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 1] = sourceImagePixelData[offset + 1]; 686 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 2] = sourceImagePixelData[offset + 0]; 687 | (*pixel)[y * bytesPerRowOutputImage + x * (*bytesPerPixel) + 3] = sourceImagePixelData[offset + 3]; 688 | } 689 | } 690 | } 691 | else 692 | goto LOAD_EXCEPTION; 693 | } 694 | break; 695 | default: 696 | goto LOAD_EXCEPTION; 697 | break; 698 | } 699 | 700 | CFRelease(data); 701 | 702 | return; 703 | LOAD_EXCEPTION: 704 | printf("Error\n"); 705 | free(*pixel); 706 | *width = 0; 707 | *height = 0; 708 | *bytesPerPixel = 0; 709 | *pixel = NULL; 710 | CFRelease(data); 711 | return; 712 | } 713 | 714 | void CGCreatePixelBufferWithImage(CGImageRef imageRef, unsigned char **pixel, int *width, int *height, int *bytesPerPixel, QH_PIXEL_TYPE pType) { 715 | size_t inputImageBytesPerPixel = CGImageGetBitsPerPixel(imageRef) / 8; 716 | 717 | switch(pType) { 718 | case QH_PIXEL_GRAYSCALE: 719 | _CGCreate8bitPixelBufferWithImage(imageRef, pixel, width, height, bytesPerPixel, pType); 720 | break; 721 | case QH_PIXEL_COLOR: 722 | _CGCreate24bitPixelBufferWithImage(imageRef, pixel, width, height, bytesPerPixel, pType); 723 | break; 724 | case QH_PIXEL_ANYCOLOR: 725 | if (inputImageBytesPerPixel == QH_BYTES_PER_PIXEL_8BIT) { 726 | _CGCreate8bitPixelBufferWithImage(imageRef, pixel, width, height, bytesPerPixel, pType); 727 | } 728 | else if (inputImageBytesPerPixel == QH_BYTES_PER_PIXEL_16BIT) { 729 | // 8 + alpha 730 | _CGCreate8bitPixelBufferWithImage(imageRef, pixel, width, height, bytesPerPixel, pType); 731 | } 732 | else if (inputImageBytesPerPixel == QH_BYTES_PER_PIXEL_24BIT) { 733 | // 24 734 | _CGCreate24bitPixelBufferWithImage(imageRef, pixel, width, height, bytesPerPixel, pType); 735 | } 736 | else if (inputImageBytesPerPixel == QH_BYTES_PER_PIXEL_32BIT) { 737 | // 32 738 | _CGCreate32bitPixelBufferWithImage(imageRef, pixel, width, height, bytesPerPixel, pType); 739 | } 740 | else { 741 | printf("Error\n"); 742 | } 743 | break; 744 | default: 745 | printf("Error\n"); 746 | break; 747 | } 748 | } 749 | 750 | #pragma mark - 751 | #pragma mark Creating CGImage 752 | 753 | CGImageRef CGImageCreateWithPixelBuffer(unsigned char *pixel, int width, int height, int bytesPerPixel, QH_PIXEL_TYPE target_pType) { 754 | if (bytesPerPixel == QH_BYTES_PER_PIXEL_8BIT) { 755 | if (target_pType == QH_PIXEL_GRAYSCALE) { 756 | CGColorSpaceRef grayColorSpace = CGColorSpaceCreateDeviceGray(); 757 | CGContextRef context = CGBitmapContextCreate(pixel, width, height, 8, width, grayColorSpace, kCGImageAlphaNone); 758 | CGImageRef image = CGBitmapContextCreateImage(context); 759 | CGColorSpaceRelease(grayColorSpace); 760 | CGContextRelease(context); 761 | return image; 762 | } 763 | else if (target_pType == QH_PIXEL_COLOR || target_pType == QH_PIXEL_ANYCOLOR) { 764 | CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 765 | 766 | unsigned char *rgbPixel = (unsigned char*)malloc(sizeof(unsigned char) * width * height * 4); 767 | 768 | for (int y = 0; y < height; y++) { 769 | for (int x = 0; x < width; x++) { 770 | rgbPixel[y * width * 4 + 4 * x + 0] = pixel[y * width + x + 0]; 771 | rgbPixel[y * width * 4 + 4 * x + 1] = pixel[y * width + x + 0]; 772 | rgbPixel[y * width * 4 + 4 * x + 2] = pixel[y * width + x + 0]; 773 | rgbPixel[y * width * 4 + 4 * x + 3] = QH_DEFAULT_ALPHA_VALUE; 774 | } 775 | } 776 | CGContextRef context = NULL; 777 | 778 | if (target_pType == QH_PIXEL_COLOR) 779 | context = CGBitmapContextCreate(rgbPixel, width, height, 8, width * 4, rgbColorSpace, kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big); 780 | if (target_pType == QH_PIXEL_ANYCOLOR) 781 | context = CGBitmapContextCreate(rgbPixel, width, height, 8, width * 4, rgbColorSpace, kCGImageAlphaLast | kCGBitmapByteOrder32Big); 782 | 783 | CGImageRef image = CGBitmapContextCreateImage(context); 784 | CGColorSpaceRelease(rgbColorSpace); 785 | free(rgbPixel); 786 | CGContextRelease(context); 787 | return image; 788 | } 789 | } 790 | else if (bytesPerPixel == QH_BYTES_PER_PIXEL_24BIT) { 791 | if (target_pType == QH_PIXEL_COLOR || target_pType == QH_PIXEL_ANYCOLOR) { 792 | CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 793 | 794 | unsigned char *rgbPixel = (unsigned char*)malloc(sizeof(unsigned char) * width * height * 4); 795 | 796 | for (int y = 0; y < height; y++) { 797 | for (int x = 0; x < width; x++) { 798 | rgbPixel[y * width * 4 + 4 * x + 0] = pixel[y * width * 3 + 3 * x + 0]; 799 | rgbPixel[y * width * 4 + 4 * x + 1] = pixel[y * width * 3 + 3 * x + 1]; 800 | rgbPixel[y * width * 4 + 4 * x + 2] = pixel[y * width * 3 + 3 * x + 2]; 801 | rgbPixel[y * width * 4 + 4 * x + 3] = QH_DEFAULT_ALPHA_VALUE; 802 | } 803 | } 804 | CGContextRef context = NULL; 805 | 806 | if (target_pType == QH_PIXEL_COLOR) 807 | context = CGBitmapContextCreate(rgbPixel, width, height, 8, width * 4, rgbColorSpace, kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big); 808 | if (target_pType == QH_PIXEL_ANYCOLOR) 809 | context = CGBitmapContextCreate(rgbPixel, width, height, 8, width * 4, rgbColorSpace, kCGImageAlphaLast | kCGBitmapByteOrder32Big); 810 | 811 | CGImageRef image = CGBitmapContextCreateImage(context); 812 | CGColorSpaceRelease(rgbColorSpace); 813 | CGContextRelease(context); 814 | free(rgbPixel); 815 | return image; 816 | } 817 | } 818 | else if (bytesPerPixel == QH_BYTES_PER_PIXEL_32BIT) { 819 | if (target_pType == QH_PIXEL_COLOR || target_pType == QH_PIXEL_ANYCOLOR) { 820 | CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 821 | 822 | unsigned char *rgbPixel = (unsigned char*)malloc(sizeof(unsigned char) * width * height * 4); 823 | 824 | for (int y = 0; y < height; y++) { 825 | for (int x = 0; x < width; x++) { 826 | rgbPixel[y * width * 4 + 4 * x + 0] = pixel[y * width * 4 + 4 * x + 0]; 827 | rgbPixel[y * width * 4 + 4 * x + 1] = pixel[y * width * 4 + 4 * x + 1]; 828 | rgbPixel[y * width * 4 + 4 * x + 2] = pixel[y * width * 4 + 4 * x + 2]; 829 | rgbPixel[y * width * 4 + 4 * x + 3] = pixel[y * width * 4 + 4 * x + 3]; 830 | } 831 | } 832 | CGContextRef context = NULL; 833 | 834 | if (target_pType == QH_PIXEL_COLOR) 835 | context = CGBitmapContextCreate(rgbPixel, width, height, 8, width * 4, rgbColorSpace, kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big); 836 | if (target_pType == QH_PIXEL_ANYCOLOR) 837 | context = CGBitmapContextCreate(rgbPixel, width, height, 8, width * 4, rgbColorSpace, kCGImageAlphaLast | kCGBitmapByteOrder32Big); 838 | 839 | CGImageRef image = CGBitmapContextCreateImage(context); 840 | CGColorSpaceRelease(rgbColorSpace); 841 | CGContextRelease(context); 842 | free(rgbPixel); 843 | return image; 844 | } 845 | } 846 | else { 847 | printf("Unsupported input or output format.\n"); 848 | } 849 | return NULL; 850 | } 851 | 852 | #pragma mark - Convert CGImage to image file binary 853 | 854 | NSData* CGImageGetPNGPresentation(CGImageRef imageRef) { 855 | UIImage *uiimage = [UIImage imageWithCGImage:imageRef]; 856 | return [uiimage PNGRepresentaion]; 857 | } 858 | 859 | NSData* CGImageGetJPEGPresentation(CGImageRef imageRef) { 860 | UIImage *uiimage = [UIImage imageWithCGImage:imageRef]; 861 | return [uiimage JPEGRepresentaion]; 862 | } 863 | 864 | #pragma mark - Resize 865 | 866 | CGImageRef CGImageCreateWithResizing(CGImageRef imageRef, float scale) { 867 | CGColorSpaceRef space = CGImageGetColorSpace(imageRef); 868 | CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); 869 | size_t bitsPerPixel = CGImageGetBitsPerPixel(imageRef); 870 | size_t bytesPerPixel = bitsPerPixel / 8; 871 | size_t resizedWidth = CGImageGetWidth(imageRef) * scale; 872 | size_t resizedHieght = CGImageGetHeight(imageRef) * scale; 873 | CGContextRef context = CGBitmapContextCreate(NULL, resizedWidth, resizedHieght, 8, resizedWidth * bytesPerPixel, space, bitmapInfo); 874 | 875 | CGContextDrawImage(context, CGRectMake(0, 0, resizedWidth, resizedHieght), imageRef); 876 | CGImageRef resizedImage = CGBitmapContextCreateImage(context); 877 | CGContextRelease(context); 878 | return resizedImage; 879 | } 880 | 881 | #pragma mark - UIImage QuartzHelpLibrary category implementation 882 | 883 | @implementation UIImage(QuartzHelpLibrary) 884 | 885 | - (NSData*)PNGRepresentaion { 886 | return UIImagePNGRepresentation(self); 887 | } 888 | 889 | - (NSData*)JPEGRepresentaion { 890 | return [self JPEGRepresentaionWithCompressionQuality:QH_DEFAULT_JPG_QUALITY]; 891 | } 892 | 893 | - (NSData*)JPEGRepresentaionWithCompressionQuality:(float)compressionQuality { 894 | return UIImageJPEGRepresentation(self, compressionQuality); 895 | } 896 | 897 | - (UIImage*)getRotatedImage { 898 | CGImageRef rotated = [self createCGImageRotated]; 899 | UIImage *output = [UIImage imageWithCGImage:rotated]; 900 | CGImageRelease(rotated); 901 | return output; 902 | } 903 | 904 | - (UIImage*)getRotatedImageWithResizing:(float)scale { 905 | CGImageRef rotated = [self createCGImageRotatedWithResizing:scale]; 906 | UIImage *output = [UIImage imageWithCGImage:rotated]; 907 | CGImageRelease(rotated); 908 | return output; 909 | } 910 | 911 | - (CGImageRef)createCGImageRotated2 { 912 | 913 | unsigned char *source = NULL; 914 | int sourceWidth = 0; 915 | int sourceHeight = 0; 916 | int sourceBytesPerPixel = 0; 917 | 918 | int targetWidth = self.size.width; 919 | int targetHeight = self.size.height; 920 | 921 | CGCreatePixelBufferWithImage(self.CGImage, &source, &sourceWidth, &sourceHeight, &sourceBytesPerPixel, QH_PIXEL_COLOR); 922 | 923 | unsigned char* target = (unsigned char*)malloc(sizeof(unsigned char) * targetWidth * targetHeight * 4); 924 | 925 | if (self.imageOrientation == UIImageOrientationUp) { 926 | for (int y = 0; y < targetHeight; y++) { 927 | for (int x = 0; x < targetWidth; x++) { 928 | target[y * targetWidth * 4 + 4 * x + 0] = source[y * sourceWidth * 3 + 3 * x + 0]; 929 | target[y * targetWidth * 4 + 4 * x + 1] = source[y * sourceWidth * 3 + 3 * x + 1]; 930 | target[y * targetWidth * 4 + 4 * x + 2] = source[y * sourceWidth * 3 + 3 * x + 2]; 931 | target[y * targetWidth * 4 + 4 * x + 3] = QH_DEFAULT_ALPHA_VALUE; 932 | } 933 | } 934 | } 935 | else if (self.imageOrientation == UIImageOrientationUpMirrored) { 936 | for (int y = 0; y < targetHeight; y++) { 937 | for (int x = 0; x < targetWidth; x++) { 938 | int tx = targetWidth - 1 - x; 939 | target[y * targetWidth * 4 + 4 * tx + 0] = source[y * sourceWidth * 3 + 3 * x + 0]; 940 | target[y * targetWidth * 4 + 4 * tx + 1] = source[y * sourceWidth * 3 + 3 * x + 1]; 941 | target[y * targetWidth * 4 + 4 * tx + 2] = source[y * sourceWidth * 3 + 3 * x + 2]; 942 | target[y * targetWidth * 4 + 4 * tx + 3] = QH_DEFAULT_ALPHA_VALUE; 943 | } 944 | } 945 | } 946 | else { 947 | } 948 | 949 | CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 950 | CGContextRef context = CGBitmapContextCreate(target, targetWidth, targetHeight, 8, targetWidth * 4, rgbColorSpace, kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big); 951 | CGImageRef image = CGBitmapContextCreateImage(context); 952 | CGColorSpaceRelease(rgbColorSpace); 953 | free(target); 954 | free(source); 955 | CGContextRelease(context); 956 | return image; 957 | } 958 | 959 | - (CGImageRef)createCGImageRotated { 960 | CGAffineTransform transform = CGAffineTransformIdentity; 961 | 962 | CGSize uiimageSize = self.size; 963 | CGSize cgimageSize = CGSizeMake(CGImageGetWidth(self.CGImage), CGImageGetHeight(self.CGImage)); 964 | CGSize outputSize = self.size; 965 | 966 | switch(self.imageOrientation) { 967 | case UIImageOrientationUp: 968 | transform = CGAffineTransformIdentity; 969 | break; 970 | case UIImageOrientationUpMirrored: 971 | transform = CGAffineTransformMakeTranslation(uiimageSize.width, 0.0); 972 | transform = CGAffineTransformScale(transform, -1.0, 1.0); 973 | break; 974 | case UIImageOrientationDown: 975 | transform = CGAffineTransformMakeTranslation(uiimageSize.width, uiimageSize.height); 976 | transform = CGAffineTransformRotate(transform, M_PI); 977 | break; 978 | case UIImageOrientationDownMirrored: 979 | transform = CGAffineTransformMakeTranslation(0.0, uiimageSize.height); 980 | transform = CGAffineTransformScale(transform, 1.0, -1.0); 981 | break; 982 | case UIImageOrientationLeftMirrored: 983 | transform = CGAffineTransformMakeTranslation(0, uiimageSize.height); 984 | transform = CGAffineTransformScale(transform, 1, -1); 985 | transform = CGAffineTransformTranslate(transform, uiimageSize.width, 0); 986 | transform = CGAffineTransformRotate(transform, M_PI / 2.0); 987 | break; 988 | case UIImageOrientationLeft: 989 | transform = CGAffineTransformMakeTranslation(uiimageSize.width, 0); 990 | transform = CGAffineTransformRotate(transform, M_PI / 2.0); 991 | break; 992 | case UIImageOrientationRightMirrored: 993 | transform = CGAffineTransformMakeTranslation(0, uiimageSize.height); 994 | transform = CGAffineTransformScale(transform, 1, -1); 995 | transform = CGAffineTransformTranslate(transform, 0, uiimageSize.height); 996 | transform = CGAffineTransformRotate(transform, -M_PI / 2.0); 997 | break; 998 | case UIImageOrientationRight: 999 | transform = CGAffineTransformMakeTranslation(0, uiimageSize.height); 1000 | transform = CGAffineTransformRotate(transform, -M_PI / 2.0); 1001 | break; 1002 | default: 1003 | return NULL; 1004 | } 1005 | 1006 | CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); 1007 | CGContextRef context = CGBitmapContextCreate(NULL, (int)outputSize.width, (int)outputSize.height, 8, (int)outputSize.width * 4, space, kCGBitmapByteOrder32Big|kCGImageAlphaNoneSkipLast); 1008 | CGContextConcatCTM(context, transform); 1009 | CGContextDrawImage(context, CGRectMake(0, 0, cgimageSize.width, cgimageSize.height), self.CGImage); 1010 | CGImageRef image = CGBitmapContextCreateImage(context); 1011 | CGContextRelease(context); 1012 | CGColorSpaceRelease(space); 1013 | 1014 | return image; 1015 | } 1016 | 1017 | - (CGImageRef)createCGImageRotatedWithResizing:(float)scale { 1018 | CGAffineTransform transform = CGAffineTransformIdentity; 1019 | 1020 | CGSize uiimageSize = self.size; 1021 | CGSize cgimageSize = CGSizeMake(CGImageGetWidth(self.CGImage), CGImageGetHeight(self.CGImage)); 1022 | CGSize outputSize = self.size; 1023 | outputSize.width *= scale; 1024 | outputSize.height *= scale; 1025 | 1026 | switch(self.imageOrientation) { 1027 | case UIImageOrientationUp: 1028 | transform = CGAffineTransformIdentity; 1029 | break; 1030 | case UIImageOrientationUpMirrored: 1031 | transform = CGAffineTransformMakeTranslation(uiimageSize.width * scale, 0.0); 1032 | transform = CGAffineTransformScale(transform, -1.0, 1.0); 1033 | break; 1034 | case UIImageOrientationDown: 1035 | transform = CGAffineTransformMakeTranslation(uiimageSize.width * scale, uiimageSize.height * scale); 1036 | transform = CGAffineTransformRotate(transform, M_PI); 1037 | break; 1038 | case UIImageOrientationDownMirrored: 1039 | transform = CGAffineTransformMakeTranslation(0.0, uiimageSize.height * scale); 1040 | transform = CGAffineTransformScale(transform, 1.0, -1.0); 1041 | break; 1042 | case UIImageOrientationLeftMirrored: 1043 | transform = CGAffineTransformMakeTranslation(0, uiimageSize.height * scale); 1044 | transform = CGAffineTransformScale(transform, 1, -1); 1045 | transform = CGAffineTransformTranslate(transform, uiimageSize.width * scale, 0); 1046 | transform = CGAffineTransformRotate(transform, M_PI / 2.0); 1047 | break; 1048 | case UIImageOrientationLeft: 1049 | transform = CGAffineTransformMakeTranslation(uiimageSize.width * scale, 0); 1050 | transform = CGAffineTransformRotate(transform, M_PI / 2.0); 1051 | break; 1052 | case UIImageOrientationRightMirrored: 1053 | transform = CGAffineTransformMakeTranslation(0, uiimageSize.height * scale); 1054 | transform = CGAffineTransformScale(transform, 1, -1); 1055 | transform = CGAffineTransformTranslate(transform, 0, uiimageSize.height * scale); 1056 | transform = CGAffineTransformRotate(transform, -M_PI / 2.0); 1057 | break; 1058 | case UIImageOrientationRight: 1059 | transform = CGAffineTransformMakeTranslation(0, uiimageSize.height * scale); 1060 | transform = CGAffineTransformRotate(transform, -M_PI / 2.0); 1061 | break; 1062 | default: 1063 | return NULL; 1064 | } 1065 | 1066 | CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); 1067 | CGContextRef context = CGBitmapContextCreate(NULL, (int)outputSize.width, (int)outputSize.height, 8, (int)outputSize.width * 4, space, kCGBitmapByteOrder32Big|kCGImageAlphaNoneSkipLast); 1068 | CGContextConcatCTM(context, transform); 1069 | CGContextDrawImage(context, CGRectMake(0, 0, cgimageSize.width * scale, cgimageSize.height * scale), self.CGImage); 1070 | CGImageRef image = CGBitmapContextCreateImage(context); 1071 | CGContextRelease(context); 1072 | CGColorSpaceRelease(space); 1073 | 1074 | return image; 1075 | } 1076 | 1077 | @end -------------------------------------------------------------------------------- /OCR-master/idcard/UserDefaults.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserDefaults.h 3 | // idcard 4 | // 5 | // Created by hxg on 16-4-10. 6 | // Copyright (c) 2016年 林英伟. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UserDefaults : NSObject 12 | 13 | + (BOOL) usingVerify; 14 | + (void) setUsingVerify:(BOOL)x; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /OCR-master/idcard/UserDefaults.m: -------------------------------------------------------------------------------- 1 | // 2 | // UserDefaults.m 3 | // idcard 4 | // 5 | // Created by hxg on 16-4-10. 6 | // Copyright (c) 2016年 林英伟. All rights reserved. 7 | // 8 | 9 | #import "UserDefaults.h" 10 | 11 | static NSString* USING_VERIFY_DEFAULTS_KEY = @"fsdfsdf";//@"usingVerify"; 12 | 13 | @implementation UserDefaults 14 | 15 | + (void) initialize { 16 | [[NSUserDefaults standardUserDefaults] 17 | registerDefaults: @{ 18 | USING_VERIFY_DEFAULTS_KEY : [NSNumber numberWithBool:YES], 19 | }]; 20 | } 21 | 22 | + (BOOL) usingVerify { 23 | return [[NSUserDefaults standardUserDefaults] boolForKey:USING_VERIFY_DEFAULTS_KEY]; 24 | } 25 | 26 | + (void) setUsingVerify:(BOOL)x { 27 | [[NSUserDefaults standardUserDefaults] setBool:x forKey:USING_VERIFY_DEFAULTS_KEY]; 28 | } 29 | 30 | @end -------------------------------------------------------------------------------- /OCR-master/idcard/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // idcard 4 | // 5 | // Created by hxg on 16-4-10. 6 | // Copyright (c) 2016年 林英伟. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Capture.h" 11 | 12 | @interface ViewController : UIViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /OCR-master/idcard/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // idcard 4 | // 5 | // Created by hxg on 16-4-10. 6 | // Copyright (c) 2016年 林英伟. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "IDCardViewController.h" 11 | #import "UserDefaults.h" 12 | 13 | @interface ViewController () 14 | 15 | @end 16 | 17 | @implementation ViewController 18 | 19 | 20 | - (void)viewDidLoad 21 | { 22 | [super viewDidLoad]; 23 | // Do any additional setup after loading the view, typically from a nib. 24 | 25 | self.view.backgroundColor = [UIColor whiteColor]; 26 | 27 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 28 | [button setTitle:@"身份证识别" forState:UIControlStateNormal]; 29 | [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; 30 | button.frame = CGRectMake(0,80, self.view.frame.size.width, 80); 31 | [self.view addSubview:button]; 32 | [button addTarget:self action:@selector(btnRecognitPressed) forControlEvents:UIControlEventTouchUpInside]; 33 | 34 | } 35 | 36 | - (void)viewWillDisappear:(BOOL)animated 37 | { 38 | [UserDefaults setUsingVerify:false]; 39 | } 40 | 41 | - (void)didReceiveMemoryWarning 42 | { 43 | [super didReceiveMemoryWarning]; 44 | // Dispose of any resources that can be recreated. 45 | } 46 | 47 | //判断是ipad还是iphone 48 | -(bool)isDevice:(NSString*)devName 49 | { 50 | NSString* deviceType = [UIDevice currentDevice].model; 51 | NSLog(@"deviceType = %@", deviceType); 52 | 53 | NSRange range = [deviceType rangeOfString:devName]; 54 | return range.location != NSNotFound; 55 | } 56 | 57 | -(void) btnRecognitPressed 58 | { 59 | IDCardViewController *controller = [[IDCardViewController alloc] initWithNibName:nil bundle:nil]; 60 | controller.verify = false; 61 | [self presentViewController:controller animated:YES completion:nil]; 62 | 63 | } 64 | 65 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation 66 | { 67 | return YES; 68 | } 69 | @end 70 | -------------------------------------------------------------------------------- /OCR-master/idcard/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /OCR-master/idcard/idcard-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | 身份证识别 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 2.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 122 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile~ipad 28 | Main_iPad 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /OCR-master/idcard/idcard-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /OCR-master/idcard/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // idcard 4 | // 5 | // Created by hxg on 14-10-10. 6 | // Copyright (c) 2014年 hxg. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /OCR-master/idcardTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /OCR-master/idcardTests/idcardTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.hxg.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /OCR-master/idcardTests/idcardTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // idcardTests.m 3 | // idcardTests 4 | // 5 | // Created by hxg on 14-10-10. 6 | // Copyright (c) 2014年 hxg. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface idcardTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation idcardTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /OCR-master/libexidcard/commondef.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/libexidcard/commondef.h -------------------------------------------------------------------------------- /OCR-master/libexidcard/dicts/zocr0.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/libexidcard/dicts/zocr0.lib -------------------------------------------------------------------------------- /OCR-master/libexidcard/excards.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/libexidcard/excards.h -------------------------------------------------------------------------------- /OCR-master/libexidcard/libexidcardios.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuedevelopment/IDCardOCR/c7679a7e5746211ea0de351e9bcd867eb343e3cb/OCR-master/libexidcard/libexidcardios.a -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IDCardOCR 2 | 身份证识别 3 | --------------------------------------------------------------------------------