IMagickLuminanceSource.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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 IMagickLuminanceSource extends LuminanceSource {
  11. public $luminances;
  12. private $dataWidth;
  13. private $dataHeight;
  14. private $left;
  15. private $top;
  16. private $image;
  17. public function __construct($image,
  18. $dataWidth,
  19. $dataHeight,
  20. $left=null,
  21. $top=null,
  22. $width=null,
  23. $height=null) {
  24. if(!$left&&!$top&&!$width&&!$height){
  25. $this->_IMagickLuminanceSource($image,$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 = $image;
  33. $this->dataWidth = $dataWidth;
  34. $this->dataHeight = $dataHeight;
  35. $this->left = $left;
  36. $this->top = $top;
  37. }
  38. public function _IMagickLuminanceSource($image, $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->image = $image;
  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. $image->setImageColorspace (\Imagick::COLORSPACE_GRAY);
  50. // $image->newPseudoImage(0, 0, "magick:rose");
  51. $pixels = $image->exportImagePixels(1, 1, $width, $height, "RGB", \Imagick::COLORSPACE_RGB);
  52. $array = array();
  53. $rgb = array();
  54. for($i=0;$i<count($pixels);$i+=3){
  55. $r = $pixels[$i]& 0xff;
  56. $g = $pixels[$i+1]& 0xff;
  57. $b = $pixels[$i+2]& 0xff;
  58. if ($r == $g && $g == $b) {
  59. // Image is already greyscale, so pick any channel.
  60. $this->luminances[] = $r;//(($r + 128) % 256) - 128;
  61. } else {
  62. // Calculate luminance cheaply, favoring green.
  63. $this->luminances[] = ($r+2*$g+$b)/4;//(((($r + 2 * $g + $b) / 4) + 128) % 256) - 128;
  64. }
  65. }
  66. }
  67. //@Override
  68. public function getRow($y, $row=null) {
  69. if ($y < 0 || $y >= $this->getHeight()) {
  70. throw new \InvalidArgumentException("Requested row is outside the image: " + y);
  71. }
  72. $width = $this->getWidth();
  73. if ($row == null || count($row) < $width) {
  74. $row = array();
  75. }
  76. $offset = ($y + $this->top) * $this->dataWidth + $this->left;
  77. $row = arraycopy($this->luminances,$offset, $row, 0, $width);
  78. return $row;
  79. }
  80. //@Override
  81. public function getMatrix() {
  82. $width = $this->getWidth();
  83. $height = $this->getHeight();
  84. // If the caller asks for the entire underlying image, save the copy and give them the
  85. // original data. The docs specifically warn that result.length must be ignored.
  86. if ($width == $this->dataWidth && $height == $this->dataHeight) {
  87. return $this->luminances;
  88. }
  89. $area = $width * $height;
  90. $matrix = array();
  91. $inputOffset = $this->top * $this->dataWidth + $this->left;
  92. // If the width matches the full width of the underlying data, perform a single copy.
  93. if ($width == $this->dataWidth) {
  94. $matrix = arraycopy($this->luminances, $inputOffset, $matrix, 0, $area);
  95. return $matrix;
  96. }
  97. // Otherwise copy one cropped row at a time.
  98. $rgb = $this->luminances;
  99. for ($y = 0; $y < $height; $y++) {
  100. $outputOffset = $y * $width;
  101. $matrix = arraycopy($rgb, $inputOffset, $matrix, $outputOffset, $width);
  102. $inputOffset += $this->dataWidth;
  103. }
  104. return $matrix;
  105. }
  106. //@Override
  107. public function isCropSupported() {
  108. return true;
  109. }
  110. //@Override
  111. public function crop($left, $top, $width, $height) {
  112. return new GDLuminanceSource($this->luminances,
  113. $this->dataWidth,
  114. $this->dataHeight,
  115. $this->left + $left,
  116. $this->top + $top,
  117. $width,
  118. $height);
  119. }
  120. }