您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

ZXQRCodeMultiReader.m 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright 2012 ZXing authors
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "ZXByteArray.h"
  17. #import "ZXDecoderResult.h"
  18. #import "ZXDetectorResult.h"
  19. #import "ZXMultiDetector.h"
  20. #import "ZXQRCodeDecoder.h"
  21. #import "ZXQRCodeDecoderMetaData.h"
  22. #import "ZXQRCodeMultiReader.h"
  23. #import "ZXResult.h"
  24. @implementation ZXQRCodeMultiReader
  25. - (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image error:(NSError **)error {
  26. return [self decodeMultiple:image hints:nil error:error];
  27. }
  28. - (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
  29. ZXBitMatrix *matrix = [image blackMatrixWithError:error];
  30. if (!matrix) {
  31. return nil;
  32. }
  33. NSMutableArray *results = [NSMutableArray array];
  34. NSArray *detectorResults = [[[ZXMultiDetector alloc] initWithImage:matrix] detectMulti:hints error:error];
  35. if (!detectorResults) {
  36. return nil;
  37. }
  38. for (ZXDetectorResult *detectorResult in detectorResults) {
  39. ZXDecoderResult *decoderResult = [[self decoder] decodeMatrix:[detectorResult bits] hints:hints error:nil];
  40. if (decoderResult) {
  41. NSMutableArray *points = [[detectorResult points] mutableCopy];
  42. // If the code was mirrored: swap the bottom-left and the top-right points.
  43. if ([decoderResult.other isKindOfClass:[ZXQRCodeDecoderMetaData class]]) {
  44. [(ZXQRCodeDecoderMetaData *)decoderResult.other applyMirroredCorrection:points];
  45. }
  46. ZXResult *result = [ZXResult resultWithText:decoderResult.text
  47. rawBytes:decoderResult.rawBytes
  48. resultPoints:points
  49. format:kBarcodeFormatQRCode];
  50. NSMutableArray *byteSegments = decoderResult.byteSegments;
  51. if (byteSegments != nil) {
  52. [result putMetadata:kResultMetadataTypeByteSegments value:byteSegments];
  53. }
  54. NSString *ecLevel = decoderResult.ecLevel;
  55. if (ecLevel != nil) {
  56. [result putMetadata:kResultMetadataTypeErrorCorrectionLevel value:ecLevel];
  57. }
  58. if ([decoderResult hasStructuredAppend]) {
  59. [result putMetadata:kResultMetadataTypeStructuredAppendSequence
  60. value:@(decoderResult.structuredAppendSequenceNumber)];
  61. [result putMetadata:kResultMetadataTypeStructuredAppendParity
  62. value:@(decoderResult.structuredAppendParity)];
  63. }
  64. [results addObject:result];
  65. }
  66. }
  67. results = [self processStructuredAppend:results];
  68. return results;
  69. }
  70. - (NSMutableArray *)processStructuredAppend:(NSMutableArray *)results {
  71. BOOL hasSA = NO;
  72. // first, check, if there is at least on SA result in the list
  73. for (ZXResult *result in results) {
  74. if (result.resultMetadata[@(kResultMetadataTypeStructuredAppendSequence)]) {
  75. hasSA = YES;
  76. break;
  77. }
  78. }
  79. if (!hasSA) {
  80. return results;
  81. }
  82. // it is, second, split the lists and built a new result list
  83. NSMutableArray *newResults = [NSMutableArray array];
  84. NSMutableArray *saResults = [NSMutableArray array];
  85. for (ZXResult *result in results) {
  86. [newResults addObject:result];
  87. if (result.resultMetadata[@(kResultMetadataTypeStructuredAppendSequence)]) {
  88. [saResults addObject:result];
  89. }
  90. }
  91. // sort and concatenate the SA list items
  92. [saResults sortUsingComparator:^NSComparisonResult(ZXResult *a, ZXResult *b) {
  93. int aNumber = [a.resultMetadata[@(kResultMetadataTypeStructuredAppendSequence)] intValue];
  94. int bNumber = [b.resultMetadata[@(kResultMetadataTypeStructuredAppendSequence)] intValue];
  95. if (aNumber < bNumber) {
  96. return NSOrderedAscending;
  97. }
  98. if (aNumber > bNumber) {
  99. return NSOrderedDescending;
  100. }
  101. return NSOrderedSame;
  102. }];
  103. NSMutableString *concatedText = [NSMutableString string];
  104. int rawBytesLen = 0;
  105. int byteSegmentLength = 0;
  106. for (ZXResult *saResult in saResults) {
  107. [concatedText appendString:saResult.text];
  108. rawBytesLen += saResult.rawBytes.length;
  109. if (saResult.resultMetadata[@(kResultMetadataTypeByteSegments)]) {
  110. for (ZXByteArray *segment in saResult.resultMetadata[@(kResultMetadataTypeByteSegments)]) {
  111. byteSegmentLength += segment.length;
  112. }
  113. }
  114. }
  115. ZXByteArray *newRawBytes = [[ZXByteArray alloc] initWithLength:rawBytesLen];
  116. ZXByteArray *newByteSegment = [[ZXByteArray alloc] initWithLength:byteSegmentLength];
  117. int newRawBytesIndex = 0;
  118. int byteSegmentIndex = 0;
  119. for (ZXResult *saResult in saResults) {
  120. memcpy(newRawBytes.array, saResult.rawBytes.array, saResult.rawBytes.length * sizeof(int8_t));
  121. newRawBytesIndex += saResult.rawBytes.length;
  122. if (saResult.resultMetadata[@(kResultMetadataTypeByteSegments)]) {
  123. for (ZXByteArray *segment in saResult.resultMetadata[@(kResultMetadataTypeByteSegments)]) {
  124. memcpy(newByteSegment.array, segment.array, segment.length * sizeof(int8_t));
  125. byteSegmentIndex += segment.length;
  126. }
  127. }
  128. }
  129. ZXResult *newResult = [[ZXResult alloc] initWithText:concatedText rawBytes:newRawBytes resultPoints:@[] format:kBarcodeFormatQRCode];
  130. if (byteSegmentLength > 0) {
  131. NSMutableArray *byteSegmentList = [NSMutableArray array];
  132. [byteSegmentList addObject:newByteSegment];
  133. [newResult putMetadata:kResultMetadataTypeByteSegments value:byteSegmentList];
  134. }
  135. [newResults addObject:newResult];
  136. return newResults;
  137. }
  138. @end