Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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 "ZXBitMatrix.h"
  17. #import "ZXByteArray.h"
  18. #import "ZXEncodeHints.h"
  19. #import "ZXPDF417.h"
  20. #import "ZXPDF417BarcodeMatrix.h"
  21. #import "ZXPDF417Dimensions.h"
  22. #import "ZXPDF417Writer.h"
  23. /**
  24. * default white space (margin) around the code
  25. */
  26. const int ZX_PDF417_WHITE_SPACE = 30;
  27. @implementation ZXPDF417Writer
  28. - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height
  29. hints:(ZXEncodeHints *)hints error:(NSError **)error {
  30. if (format != kBarcodeFormatPDF417) {
  31. [NSException raise:NSInvalidArgumentException format:@"Can only encode PDF_417, but got %d", format];
  32. }
  33. ZXPDF417 *encoder = [[ZXPDF417 alloc] init];
  34. int margin = ZX_PDF417_WHITE_SPACE;
  35. if (hints != nil) {
  36. encoder.compact = hints.pdf417Compact;
  37. encoder.compaction = hints.pdf417Compaction;
  38. if (hints.pdf417Dimensions != nil) {
  39. ZXPDF417Dimensions *dimensions = hints.pdf417Dimensions;
  40. [encoder setDimensionsWithMaxCols:dimensions.maxCols
  41. minCols:dimensions.minCols
  42. maxRows:dimensions.maxRows
  43. minRows:dimensions.minRows];
  44. }
  45. if (hints.margin) {
  46. margin = [hints.margin intValue];
  47. }
  48. if (hints.encoding > 0) {
  49. encoder.encoding = hints.encoding;
  50. }
  51. }
  52. return [self bitMatrixFromEncoder:encoder contents:contents width:width height:height margin:margin error:error];
  53. }
  54. - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height error:(NSError **)error {
  55. return [self encode:contents format:format width:width height:height hints:nil error:error];
  56. }
  57. /**
  58. * Takes encoder, accounts for width/height, and retrieves bit matrix
  59. */
  60. - (ZXBitMatrix *)bitMatrixFromEncoder:(ZXPDF417 *)encoder
  61. contents:(NSString *)contents
  62. width:(int)width
  63. height:(int)height
  64. margin:(int)margin
  65. error:(NSError **)error {
  66. int errorCorrectionLevel = 2;
  67. if (![encoder generateBarcodeLogic:contents errorCorrectionLevel:errorCorrectionLevel error:error]) {
  68. return nil;
  69. }
  70. int lineThickness = 2;
  71. int aspectRatio = 4;
  72. NSArray *originalScale = [[encoder barcodeMatrix] scaledMatrixWithXScale:lineThickness yScale:aspectRatio * lineThickness];
  73. BOOL rotated = NO;
  74. if ((height > width) ^ ([(ZXByteArray *)originalScale[0] length] < [originalScale count])) {
  75. originalScale = [self rotateArray:originalScale];
  76. rotated = YES;
  77. }
  78. int scaleX = width / [(ZXByteArray *)originalScale[0] length];
  79. int scaleY = height / [originalScale count];
  80. int scale;
  81. if (scaleX < scaleY) {
  82. scale = scaleX;
  83. } else {
  84. scale = scaleY;
  85. }
  86. if (scale > 1) {
  87. NSArray *scaledMatrix =
  88. [[encoder barcodeMatrix] scaledMatrixWithXScale:scale * lineThickness yScale:scale * aspectRatio * lineThickness];
  89. if (rotated) {
  90. scaledMatrix = [self rotateArray:scaledMatrix];
  91. }
  92. return [self bitMatrixFrombitArray:scaledMatrix margin:margin];
  93. }
  94. return [self bitMatrixFrombitArray:originalScale margin:margin];
  95. }
  96. /**
  97. * This takes an array holding the values of the PDF 417
  98. *
  99. * @param input a byte array of information with 0 is black, and 1 is white
  100. * @param margin border around the barcode
  101. * @return BitMatrix of the input
  102. */
  103. - (ZXBitMatrix *)bitMatrixFrombitArray:(NSArray *)input margin:(int)margin {
  104. // Creates the bitmatrix with extra space for whtespace
  105. ZXBitMatrix *output = [[ZXBitMatrix alloc] initWithWidth:[(ZXByteArray *)input[0] length] + 2 * margin height:(int)[input count] + 2 * margin];
  106. [output clear];
  107. for (int y = 0, yOutput = output.height - margin; y < [input count]; y++, yOutput--) {
  108. for (int x = 0; x < [(ZXByteArray *)input[0] length]; x++) {
  109. // Zero is white in the bytematrix
  110. if ([(ZXByteArray *)input[y] array][x] == 1) {
  111. [output setX:x + margin y:yOutput];
  112. }
  113. }
  114. }
  115. return output;
  116. }
  117. /**
  118. * Takes and rotates the it 90 degrees
  119. */
  120. - (NSArray *)rotateArray:(NSArray *)bitarray {
  121. NSMutableArray *temp = [NSMutableArray array];
  122. for (int i = 0; i < [(ZXByteArray *)bitarray[0] length]; i++) {
  123. [temp addObject:[[ZXByteArray alloc] initWithLength:(unsigned int)[bitarray count]]];
  124. }
  125. for (int ii = 0; ii < [bitarray count]; ii++) {
  126. // This makes the direction consistent on screen when rotating the
  127. // screen;
  128. int inverseii = (int)[bitarray count] - ii - 1;
  129. for (int jj = 0; jj < [(ZXByteArray *)bitarray[0] length]; jj++) {
  130. ZXByteArray *b = temp[jj];
  131. b.array[inverseii] = [(ZXByteArray *)bitarray[ii] array][jj];
  132. }
  133. }
  134. return temp;
  135. }
  136. @end