ImageMagickAdapter.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. namespace splitbrain\slika;
  3. /**
  4. * Image Processing Adapter for ImageMagick's command line utility `convert`
  5. */
  6. class ImageMagickAdapter extends Adapter
  7. {
  8. /** @var array the CLI arguments to run imagemagick */
  9. protected $args = [];
  10. /** @inheritDoc */
  11. public function __construct($imagepath, $options = [])
  12. {
  13. parent::__construct($imagepath, $options);
  14. if (!is_executable($this->options['imconvert'])) {
  15. throw new Exception('Can not find or run ' . $this->options['imconvert']);
  16. }
  17. $this->args[] = $this->options['imconvert'];
  18. $this->args[] = $imagepath;
  19. }
  20. /** @inheritDoc */
  21. public function autorotate()
  22. {
  23. $this->args[] = '-auto-orient';
  24. return $this;
  25. }
  26. /** @inheritDoc */
  27. public function rotate($orientation)
  28. {
  29. $orientation = (int)$orientation;
  30. if ($orientation < 0 || $orientation > 8) {
  31. throw new Exception('Unknown rotation given');
  32. }
  33. // rotate
  34. $this->args[] = '-rotate';
  35. if (in_array($orientation, [3, 4])) {
  36. $this->args[] = '180';
  37. } elseif (in_array($orientation, [5, 6])) {
  38. $this->args[] = '90';
  39. } elseif (in_array($orientation, [7, 8])) {
  40. $this->args[] = '270';
  41. }
  42. // additionally flip
  43. if (in_array($orientation, [2, 5, 7, 4])) {
  44. $this->args[] = '-flop';
  45. }
  46. return $this;
  47. }
  48. /**
  49. * @inheritDoc
  50. * @throws Exception
  51. */
  52. public function resize($width, $height)
  53. {
  54. if ($width == 0 && $height == 0) {
  55. throw new Exception('You can not resize to 0x0');
  56. }
  57. if ($width == 0) $width = '';
  58. if ($height == 0) $height = '';
  59. $size = $width . 'x' . $height;
  60. $this->args[] = '-resize';
  61. $this->args[] = $size;
  62. return $this;
  63. }
  64. /**
  65. * @inheritDoc
  66. * @throws Exception
  67. */
  68. public function crop($width, $height)
  69. {
  70. if ($width == 0 && $height == 0) {
  71. throw new Exception('You can not crop to 0x0');
  72. }
  73. if ($width == 0) $width = $height;
  74. if ($height == 0) $height = $width;
  75. $size = $width . 'x' . $height;
  76. $this->args[] = '-resize';
  77. $this->args[] = "$size^";
  78. $this->args[] = '-gravity';
  79. $this->args[] = 'center';
  80. $this->args[] = '-crop';
  81. $this->args[] = "$size+0+0";
  82. $this->args[] = '+repage';
  83. return $this;
  84. }
  85. /**
  86. * @inheritDoc
  87. * @throws Exception
  88. */
  89. public function save($path, $extension = '')
  90. {
  91. if ($extension === 'jpg') {
  92. $extension = 'jpeg';
  93. }
  94. $this->args[] = '-quality';
  95. $this->args[] = $this->options['quality'];
  96. if ($extension !== '') $path = $extension . ':' . $path;
  97. $this->args[] = $path;
  98. $args = array_map('escapeshellarg', $this->args);
  99. $cmd = join(' ', $args);
  100. $output = [];
  101. $return = 0;
  102. exec($cmd, $output, $return);
  103. if ($return !== 0) {
  104. throw new Exception('ImageMagick returned non-zero exit code for ' . $cmd);
  105. }
  106. }
  107. }