vendor/gregwar/image/Gregwar/Image/Adapter/Common.php line 82

Open in your IDE?
  1. <?php
  2. namespace Gregwar\Image\Adapter;
  3. abstract class Common extends Adapter
  4. {
  5.     /**
  6.      * {@inheritdoc}
  7.      */
  8.     public function zoomCrop($width$height$background 'transparent'$xPosLetter 'center'$yPosLetter 'center')
  9.     {
  10.         $originalWidth $this->width();
  11.         $originalHeight $this->height();
  12.         // Calculate the different ratios
  13.         $originalRatio $originalWidth $originalHeight;
  14.         $newRatio $width $height;
  15.         // Compare ratios
  16.         if ($originalRatio $newRatio) {
  17.             // Original image is wider
  18.             $newHeight $height;
  19.             $newWidth = (int) $height $originalRatio;
  20.         } else {
  21.             // Equal width or smaller
  22.             $newHeight = (int) $width $originalRatio;
  23.             $newWidth $width;
  24.         }
  25.         // Perform resize
  26.         $this->resize($newWidth$newHeight$backgroundtrue);
  27.         // Define x position
  28.         switch ($xPosLetter) {
  29.             case 'L':
  30.             case 'left':
  31.                 $xPos 0;
  32.                 break;
  33.             case 'R':
  34.             case 'right':
  35.                 $xPos = (int) $newWidth $width;
  36.                 break;
  37.             case 'center':
  38.                 $xPos = (int) ($newWidth $width) / 2;
  39.                 break;
  40.             default:
  41.                 $factorW $newWidth $originalWidth;
  42.                 $xPos $xPosLetter $factorW;
  43.                 // If the desired cropping position goes beyond the width then
  44.                 // set the crop to be within the correct bounds.
  45.                 if ($xPos $width $newWidth) {
  46.                     $xPos = (int) $newWidth $width;
  47.                 }
  48.         }
  49.         // Define y position
  50.         switch ($yPosLetter) {
  51.             case 'T':
  52.             case 'top':
  53.                 $yPos 0;
  54.                 break;
  55.             case 'B':
  56.             case 'bottom':
  57.                 $yPos = (int) $newHeight $height;
  58.                 break;
  59.             case 'center':
  60.                 $yPos = (int) ($newHeight $height) / 2;
  61.                 break;
  62.             default:
  63.                 $factorH $newHeight $originalHeight;
  64.                 $yPos $yPosLetter $factorH;
  65.                 // If the desired cropping position goes beyond the height then
  66.                 // set the crop to be within the correct bounds.
  67.                 if ($yPos $height $newHeight) {
  68.                     $yPos = (int) $newHeight $height;
  69.                 }
  70.         }
  71.         // Crop image to reach desired size
  72.         $this->crop($xPos$yPos$width$height);
  73.         return $this;
  74.     }
  75.     /**
  76.      * Resizes the image forcing the destination to have exactly the
  77.      * given width and the height.
  78.      *
  79.      * @param int $w  the width
  80.      * @param int $h  the height
  81.      * @param int $bg the background
  82.      */
  83.     public function forceResize($width null$height null$background 'transparent')
  84.     {
  85.         return $this->resize($width$height$backgroundtrue);
  86.     }
  87.     /**
  88.      * {@inheritdoc}
  89.      */
  90.     public function scaleResize($width null$height null$background 'transparent'$crop false)
  91.     {
  92.         return $this->resize($width$height$backgroundfalsetrue$crop);
  93.     }
  94.     /**
  95.      * {@inheritdoc}
  96.      */
  97.     public function cropResize($width null$height null$background 'transparent')
  98.     {
  99.         return $this->resize($width$height$backgroundfalsefalsetrue);
  100.     }
  101.     /**
  102.      * Read exif rotation from file and apply it.
  103.      */
  104.     public function fixOrientation()
  105.     {
  106.         if (!in_array(exif_imagetype($this->source->getInfos()), array(
  107.             IMAGETYPE_JPEG,
  108.             IMAGETYPE_TIFF_II,
  109.             IMAGETYPE_TIFF_MM,
  110.         ))) {
  111.             return $this;
  112.         }
  113.         if (!extension_loaded('exif')) {
  114.             throw new \RuntimeException('You need to EXIF PHP Extension to use this function');
  115.         }
  116.         $exif = @exif_read_data($this->source->getInfos());
  117.         if ($exif === false || !array_key_exists('Orientation'$exif)) {
  118.             return $this;
  119.         }
  120.         return $this->applyExifOrientation($exif['Orientation']);
  121.     }
  122.     /**
  123.      * Apply orientation using Exif orientation value.
  124.      */
  125.     public function applyExifOrientation($exif_orienation)
  126.     {
  127.         switch ($exif_orienation) {
  128.             case 1:
  129.                 break;
  130.             case 2:
  131.                 $this->flip(falsetrue);
  132.                 break;
  133.             case 3// 180 rotate left
  134.                 $this->rotate(180);
  135.                 break;
  136.             case 4// vertical flip
  137.                 $this->flip(truefalse);
  138.                 break;
  139.             case 5// vertical flip + 90 rotate right
  140.                 $this->flip(truefalse);
  141.                 $this->rotate(-90);
  142.                 break;
  143.             case 6// 90 rotate right
  144.                 $this->rotate(-90);
  145.                 break;
  146.             case 7// horizontal flip + 90 rotate right
  147.                 $this->flip(falsetrue);
  148.                 $this->rotate(-90);
  149.                 break;
  150.             case 8// 90 rotate left
  151.                 $this->rotate(90);
  152.                 break;
  153.         }
  154.         return $this;
  155.     }
  156.     /**
  157.      * Opens the image.
  158.      */
  159.     abstract protected function openGif($file);
  160.     abstract protected function openJpeg($file);
  161.     abstract protected function openPng($file);
  162.     abstract protected function openWebp($file);
  163.     /**
  164.      * Creates an image.
  165.      */
  166.     abstract protected function createImage($width$height);
  167.     /**
  168.      * Creating an image using $data.
  169.      */
  170.     abstract protected function createImageFromData($data);
  171.     /**
  172.      * Loading image from $resource.
  173.      */
  174.     protected function loadResource($resource)
  175.     {
  176.         $this->resource $resource;
  177.     }
  178.     protected function loadFile($file$type)
  179.     {
  180.         if (!$this->supports($type)) {
  181.             throw new \RuntimeException('Type '.$type.' is not supported by GD');
  182.         }
  183.         if ($type == 'jpeg') {
  184.             $this->openJpeg($file);
  185.         }
  186.         if ($type == 'gif') {
  187.             $this->openGif($file);
  188.         }
  189.         if ($type == 'png') {
  190.             $this->openPng($file);
  191.         }
  192.         if ($type == 'webp') {
  193.             $this->openWebp($file);
  194.         }
  195.         if (false === $this->resource) {
  196.             throw new \UnexpectedValueException('Unable to open file ('.$file.')');
  197.         } else {
  198.             $this->convertToTrueColor();
  199.         }
  200.     }
  201.     /**
  202.      * {@inheritdoc}
  203.      */
  204.     public function init()
  205.     {
  206.         $source $this->source;
  207.         if ($source instanceof \Gregwar\Image\Source\File) {
  208.             $this->loadFile($source->getFile(), $source->guessType());
  209.         } elseif ($source instanceof \Gregwar\Image\Source\Create) {
  210.             $this->createImage($source->getWidth(), $source->getHeight());
  211.         } elseif ($source instanceof \Gregwar\Image\Source\Data) {
  212.             $this->createImageFromData($source->getData());
  213.         } elseif ($source instanceof \Gregwar\Image\Source\Resource) {
  214.             $this->loadResource($source->getResource());
  215.         } else {
  216.             throw new \Exception('Unsupported image source type '.get_class($source));
  217.         }
  218.         return $this;
  219.     }
  220.     
  221.     /**
  222.      * {@inheritdoc}
  223.      */
  224.     public function deinit()
  225.     {
  226.         $this->resource null;
  227.     }
  228.     /**
  229.      * {@inheritdoc}
  230.      */
  231.     public function resize($width null$height null$background 'transparent'$force false$rescale false$crop false)
  232.     {
  233.         $current_width $this->width();
  234.         $current_height $this->height();
  235.         $new_width 0;
  236.         $new_height 0;
  237.         $scale 1.0;
  238.         if ($height === null && preg_match('#^(.+)%$#mUsi'$width$matches)) {
  239.             $width round($current_width * ((float) $matches[1] / 100.0));
  240.             $height round($current_height * ((float) $matches[1] / 100.0));
  241.         }
  242.         if (!$rescale && (!$force || $crop)) {
  243.             if ($width != null && $current_width $width) {
  244.                 $scale $current_width $width;
  245.             }
  246.             if ($height != null && $current_height $height) {
  247.                 if ($current_height $height $scale) {
  248.                     $scale $current_height $height;
  249.                 }
  250.             }
  251.         } else {
  252.             if ($width != null) {
  253.                 $scale $current_width $width;
  254.                 $new_width $width;
  255.             }
  256.             if ($height != null) {
  257.                 if ($width != null && $rescale) {
  258.                     $scale max($scale$current_height $height);
  259.                 } else {
  260.                     $scale $current_height $height;
  261.                 }
  262.                 $new_height $height;
  263.             }
  264.         }
  265.         if (!$force || $width == null || $rescale) {
  266.             $new_width round($current_width $scale);
  267.         }
  268.         if (!$force || $height == null || $rescale) {
  269.             $new_height round($current_height $scale);
  270.         }
  271.         if ($width == null || $crop) {
  272.             $width $new_width;
  273.         }
  274.         if ($height == null || $crop) {
  275.             $height $new_height;
  276.         }
  277.         $this->doResize($background$width$height$new_width$new_height);
  278.     }
  279.     /**
  280.      * Trim background color arround the image.
  281.      *
  282.      * @param int $bg the background
  283.      */
  284.     protected function _trimColor($background 'transparent')
  285.     {
  286.         $width $this->width();
  287.         $height $this->height();
  288.         $b_top 0;
  289.         $b_lft 0;
  290.         $b_btm $height 1;
  291.         $b_rt $width 1;
  292.         //top
  293.         for (; $b_top $height; ++$b_top) {
  294.             for ($x 0$x $width; ++$x) {
  295.                 if ($this->getColor($x$b_top) != $background) {
  296.                     break 2;
  297.                 }
  298.             }
  299.         }
  300.         // bottom
  301.         for (; $b_btm >= 0; --$b_btm) {
  302.             for ($x 0$x $width; ++$x) {
  303.                 if ($this->getColor($x$b_btm) != $background) {
  304.                     break 2;
  305.                 }
  306.             }
  307.         }
  308.         // left
  309.         for (; $b_lft $width; ++$b_lft) {
  310.             for ($y $b_top$y <= $b_btm; ++$y) {
  311.                 if ($this->getColor($b_lft$y) != $background) {
  312.                     break 2;
  313.                 }
  314.             }
  315.         }
  316.         // right
  317.         for (; $b_rt >= 0; --$b_rt) {
  318.             for ($y $b_top$y <= $b_btm; ++$y) {
  319.                 if ($this->getColor($b_rt$y) != $background) {
  320.                     break 2;
  321.                 }
  322.             }
  323.         }
  324.         ++$b_btm;
  325.         ++$b_rt;
  326.         $this->crop($b_lft$b_top$b_rt $b_lft$b_btm $b_top);
  327.     }
  328.     /**
  329.      * Resizes the image to an image having size of $target_width, $target_height, using
  330.      * $new_width and $new_height and padding with $bg color.
  331.      */
  332.     abstract protected function doResize($bg$target_width$target_height$new_width$new_height);
  333.     /**
  334.      * Gets the color of the $x, $y pixel.
  335.      */
  336.     abstract protected function getColor($x$y);
  337.     /**
  338.      * {@inheritdoc}
  339.      */
  340.     public function enableProgressive()
  341.     {
  342.         throw new \Exception('The Adapter '.$this->getName().' does not support Progressive Image loading');
  343.     }
  344.     /**
  345.      * This does nothing, but can be used to tag a ressource for instance (having a final image hash
  346.      * for the cache different depending on the tag)
  347.      */
  348.     public function tag($tag)
  349.     {
  350.     }
  351. }