QRSvgWithLogo.php 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <?php
  2. /**
  3. * Class QRSvgWithLogo
  4. *
  5. * @created 05.03.2022
  6. * @author smiley <smiley@chillerlan.net>
  7. * @copyright 2022 smiley
  8. * @license MIT
  9. */
  10. namespace chillerlan\QRCodeExamples;
  11. use chillerlan\QRCode\Output\QRMarkup;
  12. use function file_get_contents, sprintf;
  13. /**
  14. * Create SVG QR Codes with embedded logos (that are also SVG)
  15. */
  16. class QRSvgWithLogo extends QRMarkup{
  17. /**
  18. * SVG output
  19. *
  20. * @see https://github.com/codemasher/php-qrcode/pull/5
  21. * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg
  22. * @see https://www.sarasoueidan.com/demos/interactive-svg-coordinate-system/
  23. */
  24. protected function svg(bool $saveToFile):string{
  25. $size = (int)ceil($this->moduleCount * $this->options->svgLogoScale);
  26. // we're calling QRMatrix::setLogoSpace() manually, so QROptions::$addLogoSpace has no effect here
  27. $this->matrix->setLogoSpace($size, $size);
  28. $svg = $this->svgHeader();
  29. if(!empty($this->options->svgDefs)){
  30. $svg .= sprintf('<defs>%1$s%2$s</defs>%2$s', $this->options->svgDefs, $this->options->eol);
  31. }
  32. $svg .= $this->svgPaths();
  33. $svg .= $this->getLogo();
  34. // close svg
  35. $svg .= sprintf('%1$s</svg>%1$s', $this->options->eol);
  36. // transform to data URI only when not saving to file
  37. if(!$saveToFile && $this->options->imageBase64){
  38. $svg = $this->base64encode($svg, 'image/svg+xml');
  39. }
  40. return $svg;
  41. }
  42. /**
  43. * returns a <g> element that contains the SVG logo and positions it properly within the QR Code
  44. *
  45. * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g
  46. * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform
  47. */
  48. protected function getLogo():string{
  49. // @todo: customize the <g> element to your liking (css class, style...)
  50. return sprintf(
  51. '%5$s<g transform="translate(%1$s %1$s) scale(%2$s)" class="%3$s">%5$s %4$s%5$s</g>',
  52. ($this->moduleCount - ($this->moduleCount * $this->options->svgLogoScale)) / 2,
  53. $this->options->svgLogoScale,
  54. $this->options->svgLogoCssClass,
  55. file_get_contents($this->options->svgLogo),
  56. $this->options->eol
  57. );
  58. }
  59. }