QRCodeImage.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. /**
  3. * This file is part of the phpQr package
  4. *
  5. * See @see QRCode class for description of package and license.
  6. */
  7. /**
  8. * Import necessary dependencies
  9. */
  10. require_once 'QRCodeException.php';
  11. /**
  12. * Derived exception class
  13. *
  14. * @author Maik Greubel <[email protected]>
  15. * @package phpQr
  16. */
  17. class QRCodeImageException extends QRCodeException{};
  18. /**
  19. * This class provides all needed functionality to create an image out of an QRCode bitmap
  20. *
  21. * @author Maik Greubel <[email protected]>
  22. * @package phpQr
  23. */
  24. class QRCodeImage
  25. {
  26. /**
  27. * The previously created QRCode
  28. *
  29. * @var QRCode
  30. */
  31. private $qrcode;
  32. /**
  33. * The desired width of the destination image
  34. *
  35. * @var int
  36. */
  37. private $width;
  38. /**
  39. * The desired height of the destination image
  40. *
  41. * @var int
  42. */
  43. private $height;
  44. /**
  45. * Quality of the destination image
  46. *
  47. * @var int
  48. */
  49. private $quality;
  50. /**
  51. * The image buffer provided by GD function imagecreate()
  52. *
  53. * @var resource
  54. */
  55. private $img;
  56. /**
  57. * Create a new QRCodeImage instance
  58. *
  59. * @param QRCode $qrcode The previously created QRCode
  60. * @param int $width The desired width of the destination image
  61. * @param int $height The desired height of the destination image
  62. * @param int $quality The desired quality of the destination image
  63. */
  64. public function __construct(QRCode $qrcode, $width, $height, $quality = 90)
  65. {
  66. $this->qrcode = $qrcode;
  67. $this->width = $width;
  68. $this->height = $height;
  69. $this->quality = $quality;
  70. $this->img = null;
  71. }
  72. /**
  73. * Draw the image
  74. */
  75. public function draw()
  76. {
  77. $moduleCount = $this->qrcode->getModuleCount();
  78. $tileWidth = $this->width / $moduleCount;
  79. $tileHeight = $this->height / $moduleCount;
  80. $this->img = imagecreatetruecolor($this->width, $this->height);
  81. if($this->img)
  82. {
  83. $fg = imagecolorallocate($this->img, 0, 0, 0);
  84. if($fg === false)
  85. {
  86. $this->finish();
  87. throw new QRCodeImageException('Could not allocate foreground color!');
  88. }
  89. $bg = imagecolorallocate($this->img, 255, 255, 255);
  90. if($bg === false)
  91. {
  92. $this->finish();
  93. throw new QRCodeImageException('Could not allocate background color!');
  94. }
  95. for($row = 0; $row < $moduleCount; $row++)
  96. {
  97. for($col = 0; $col < $moduleCount; $col++)
  98. {
  99. $fillStyle = $this->qrcode->isDark($row, $col) ? $fg : $bg;
  100. $x = round($col * $tileWidth);
  101. $y = round($row * $tileHeight);
  102. $w = (ceil(($col + 1) * $tileWidth) - floor($col * $tileWidth));
  103. if($x + $w > $this->width)
  104. {
  105. $w = $this->width - $x;
  106. }
  107. $h = (ceil(($row + 1) * $tileWidth) - floor($row * $tileWidth));
  108. if($y + $h > $this->height)
  109. {
  110. $h = $this->height - $y;
  111. }
  112. if(!imagefilledrectangle($this->img, $x, $y, $x + $w, $y + $h, $fillStyle))
  113. {
  114. $this->finish();
  115. throw new QRCodeImageException(sprintf('Could not fill the rectangle using desired coordinates (x = %d, y = %d, w = %d, h = %d, c = %d)',
  116. $x, $y, $w, $h, $fillStyle));
  117. }
  118. }
  119. }
  120. }
  121. else
  122. {
  123. throw new QRCodeImageException('Could not create true color image buffer!');
  124. }
  125. }
  126. /**
  127. * Store the image
  128. *
  129. * @param string $filename
  130. */
  131. public function store($filename)
  132. {
  133. if($this->img)
  134. {
  135. if(!imagejpeg($this->img, $filename, $this->quality))
  136. {
  137. throw new QRCodeImageException(sprintf('Could not save image to file %s', $filename));
  138. }
  139. }
  140. }
  141. /**
  142. * Return the image as string
  143. */
  144. public function getImage()
  145. {
  146. if($this->img)
  147. {
  148. ob_start();
  149. if(!imagejpeg($this->img, null, $this->quality))
  150. {
  151. ob_end_flush();
  152. throw new QRCodeImageException('Could not create a jpeg out of the image buffer!');
  153. }
  154. $out = ob_get_clean();
  155. return $out;
  156. }
  157. throw new QRCodeImageException('No image data available!');
  158. }
  159. /**
  160. * Clean the image buffer
  161. */
  162. public function finish()
  163. {
  164. if($this->img)
  165. {
  166. imagedestroy($this->img);
  167. $this->img = null;
  168. }
  169. }
  170. }