BinaryBitmap.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <?php
  2. /*
  3. * Copyright 2009 ZXing authors
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. namespace Zxing;
  18. use Zxing\Common\BitMatrix;
  19. /**
  20. * This class is the core bitmap class used by ZXing to represent 1 bit data. Reader objects
  21. * accept a BinaryBitmap and attempt to decode it.
  22. *
  23. * @author dswitkin@google.com (Daniel Switkin)
  24. */
  25. final class BinaryBitmap
  26. {
  27. private $binarizer;
  28. private $matrix;
  29. public function __construct(Binarizer $binarizer)
  30. {
  31. if ($binarizer === null) {
  32. throw new \InvalidArgumentException("Binarizer must be non-null.");
  33. }
  34. $this->binarizer = $binarizer;
  35. }
  36. /**
  37. * @return int The width of the bitmap.
  38. */
  39. public function getWidth()
  40. {
  41. return $this->binarizer->getWidth();
  42. }
  43. /**
  44. * @return int The height of the bitmap.
  45. */
  46. public function getHeight()
  47. {
  48. return $this->binarizer->getHeight();
  49. }
  50. /**
  51. * Converts one row of luminance data to 1 bit data. May actually do the conversion, or return
  52. * cached data. Callers should assume this method is expensive and call it as seldom as possible.
  53. * This method is intended for decoding 1D barcodes and may choose to apply sharpening.
  54. *
  55. * @param y The row to fetch, which must be in [0, bitmap height)
  56. * @param row An optional preallocated array. If null or too small, it will be ignored.
  57. * If used, the Binarizer will call BitArray.clear(). Always use the returned object.
  58. *
  59. * @return array The array of bits for this row (true means black).
  60. * @throws NotFoundException if row can't be binarized
  61. */
  62. public function getBlackRow($y, $row)
  63. {
  64. return $this->binarizer->getBlackRow($y, $row);
  65. }
  66. /**
  67. * @return bool Whether this bitmap can be cropped.
  68. */
  69. public function isCropSupported()
  70. {
  71. return $this->binarizer->getLuminanceSource()->isCropSupported();
  72. }
  73. /**
  74. * Returns a new object with cropped image data. Implementations may keep a reference to the
  75. * original data rather than a copy. Only callable if isCropSupported() is true.
  76. *
  77. * @param left The left coordinate, which must be in [0,getWidth())
  78. * @param top The top coordinate, which must be in [0,getHeight())
  79. * @param width The width of the rectangle to crop.
  80. * @param height The height of the rectangle to crop.
  81. *
  82. * @return BinaryBitmap A cropped version of this object.
  83. */
  84. public function crop($left, $top, $width, $height)
  85. {
  86. $newSource = $this->binarizer->getLuminanceSource()->crop($left, $top, $width, $height);
  87. return new BinaryBitmap($this->binarizer->createBinarizer($newSource));
  88. }
  89. /**
  90. * @return Whether this bitmap supports counter-clockwise rotation.
  91. */
  92. public function isRotateSupported()
  93. {
  94. return $this->binarizer->getLuminanceSource()->isRotateSupported();
  95. }
  96. /**
  97. * Returns a new object with rotated image data by 90 degrees counterclockwise.
  98. * Only callable if {@link #isRotateSupported()} is true.
  99. *
  100. * @return BinaryBitmap A rotated version of this object.
  101. */
  102. public function rotateCounterClockwise()
  103. {
  104. $newSource = $this->binarizer->getLuminanceSource()->rotateCounterClockwise();
  105. return new BinaryBitmap($this->binarizer->createBinarizer($newSource));
  106. }
  107. /**
  108. * Returns a new object with rotated image data by 45 degrees counterclockwise.
  109. * Only callable if {@link #isRotateSupported()} is true.
  110. *
  111. * @return BinaryBitmap A rotated version of this object.
  112. */
  113. public function rotateCounterClockwise45()
  114. {
  115. $newSource = $this->binarizer->getLuminanceSource()->rotateCounterClockwise45();
  116. return new BinaryBitmap($this->binarizer->createBinarizer($newSource));
  117. }
  118. public function toString()
  119. {
  120. try {
  121. return $this->getBlackMatrix()->toString();
  122. } catch (NotFoundException $e) {
  123. }
  124. return '';
  125. }
  126. /**
  127. * Converts a 2D array of luminance data to 1 bit. As above, assume this method is expensive
  128. * and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or
  129. * may not apply sharpening. Therefore, a row from this matrix may not be identical to one
  130. * fetched using getBlackRow(), so don't mix and match between them.
  131. *
  132. * @return BitMatrix The 2D array of bits for the image (true means black).
  133. * @throws NotFoundException if image can't be binarized to make a matrix
  134. */
  135. public function getBlackMatrix()
  136. {
  137. // The matrix is created on demand the first time it is requested, then cached. There are two
  138. // reasons for this:
  139. // 1. This work will never be done if the caller only installs 1D Reader objects, or if a
  140. // 1D Reader finds a barcode before the 2D Readers run.
  141. // 2. This work will only be done once even if the caller installs multiple 2D Readers.
  142. if ($this->matrix === null) {
  143. $this->matrix = $this->binarizer->getBlackMatrix();
  144. }
  145. return $this->matrix;
  146. }
  147. }