GDLuminanceSource.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <?php
  2. namespace Zxing;
  3. /**
  4. * This class is used to help decode images from files which arrive as GD Resource
  5. * It does not support rotation.
  6. *
  7. *
  8. *
  9. */
  10. final class GDLuminanceSource extends LuminanceSource {
  11. public $luminances;
  12. private $dataWidth;
  13. private $dataHeight;
  14. private $left;
  15. private $top;
  16. private $gdImage;
  17. public function __construct($gdImage,
  18. $dataWidth,
  19. $dataHeight,
  20. $left=null,
  21. $top=null,
  22. $width=null,
  23. $height=null) {
  24. if(!$left&&!$top&&!$width&&!$height){
  25. $this->GDLuminanceSource($gdImage,$dataWidth,$dataHeight);
  26. return;
  27. }
  28. parent::__construct($width, $height);
  29. if ($left + $width > $dataWidth || $top + $height > $dataHeight) {
  30. throw new \InvalidArgumentException("Crop rectangle does not fit within image data.");
  31. }
  32. $this->luminances = $gdImage;
  33. $this->dataWidth = $dataWidth;
  34. $this->dataHeight = $dataHeight;
  35. $this->left = $left;
  36. $this->top = $top;
  37. }
  38. public function GDLuminanceSource($gdImage, $width, $height)
  39. {
  40. parent::__construct($width, $height);
  41. $this->dataWidth = $width;
  42. $this->dataHeight = $height;
  43. $this->left = 0;
  44. $this->top = 0;
  45. $this->$gdImage = $gdImage;
  46. // In order to measure pure decoding speed, we convert the entire image to a greyscale array
  47. // up front, which is the same as the Y channel of the YUVLuminanceSource in the real app.
  48. $this->luminances = array();
  49. //$this->luminances = $this->grayScaleToBitmap($this->grayscale());
  50. $array = array();
  51. $rgb = array();
  52. for($j=0;$j<$height;$j++){
  53. for($i=0;$i<$width;$i++){
  54. $argb = imagecolorat($this->$gdImage, $i, $j);
  55. $pixel = imagecolorsforindex($this->$gdImage, $argb);
  56. $r = $pixel['red'];
  57. $g = $pixel['green'];
  58. $b = $pixel['blue'];
  59. if ($r == $g && $g == $b) {
  60. // Image is already greyscale, so pick any channel.
  61. $this->luminances[] = $r;//(($r + 128) % 256) - 128;
  62. } else {
  63. // Calculate luminance cheaply, favoring green.
  64. $this->luminances[] = ($r+2*$g+$b)/4;//(((($r + 2 * $g + $b) / 4) + 128) % 256) - 128;
  65. }
  66. }
  67. }
  68. /*
  69. for ($y = 0; $y < $height; $y++) {
  70. $offset = $y * $width;
  71. for ($x = 0; $x < $width; $x++) {
  72. $pixel = $pixels[$offset + $x];
  73. $r = ($pixel >> 16) & 0xff;
  74. $g = ($pixel >> 8) & 0xff;
  75. $b = $pixel & 0xff;
  76. if ($r == $g && $g == $b) {
  77. // Image is already greyscale, so pick any channel.
  78. $this->luminances[intval($offset + $x)] = (($r+128) % 256) - 128;
  79. } else {
  80. // Calculate luminance cheaply, favoring green.
  81. $this->luminances[intval($offset + $x)] = (((($r + 2 * $g + $b) / 4)+128)%256) - 128;
  82. }
  83. }
  84. */
  85. //}
  86. // $this->luminances = $this->grayScaleToBitmap($this->luminances);
  87. }
  88. //@Override
  89. public function getRow($y, $row=null) {
  90. if ($y < 0 || $y >= $this->getHeight()) {
  91. throw new \InvalidArgumentException("Requested row is outside the image: " + y);
  92. }
  93. $width = $this->getWidth();
  94. if ($row == null || count($row) < $width) {
  95. $row = array();
  96. }
  97. $offset = ($y + $this->top) * $this->dataWidth + $this->left;
  98. $row = arraycopy($this->luminances,$offset, $row, 0, $width);
  99. return $row;
  100. }
  101. //@Override
  102. public function getMatrix() {
  103. $width = $this->getWidth();
  104. $height = $this->getHeight();
  105. // If the caller asks for the entire underlying image, save the copy and give them the
  106. // original data. The docs specifically warn that result.length must be ignored.
  107. if ($width == $this->dataWidth && $height == $this->dataHeight) {
  108. return $this->luminances;
  109. }
  110. $area = $width * $height;
  111. $matrix = array();
  112. $inputOffset = $this->top * $this->dataWidth + $this->left;
  113. // If the width matches the full width of the underlying data, perform a single copy.
  114. if ($width == $this->dataWidth) {
  115. $matrix = arraycopy($this->luminances, $inputOffset, $matrix, 0, $area);
  116. return $matrix;
  117. }
  118. // Otherwise copy one cropped row at a time.
  119. $rgb = $this->luminances;
  120. for ($y = 0; $y < $height; $y++) {
  121. $outputOffset = $y * $width;
  122. $matrix = arraycopy($rgb, $inputOffset, $matrix, $outputOffset, $width);
  123. $inputOffset += $this->dataWidth;
  124. }
  125. return $matrix;
  126. }
  127. //@Override
  128. public function isCropSupported() {
  129. return true;
  130. }
  131. //@Override
  132. public function crop($left, $top, $width, $height) {
  133. return new GDLuminanceSource($this->luminances,
  134. $this->dataWidth,
  135. $this->dataHeight,
  136. $this->left + $left,
  137. $this->top + $top,
  138. $width,
  139. $height);
  140. }
  141. }