/**
  * @param Thumbnail $thumbnail
  * @return void
  * @throws Exception\NoThumbnailAvailableException
  */
 public function refresh(Thumbnail $thumbnail)
 {
     try {
         $filenameWithoutExtension = pathinfo($thumbnail->getOriginalAsset()->getResource()->getFilename(), PATHINFO_FILENAME);
         $temporaryLocalCopyFilename = $thumbnail->getOriginalAsset()->getResource()->createTemporaryLocalCopy();
         $documentFile = sprintf(in_array($thumbnail->getOriginalAsset()->getResource()->getFileExtension(), $this->getOption('paginableDocuments')) ? '%s[0]' : '%s', $temporaryLocalCopyFilename);
         $width = $thumbnail->getConfigurationValue('width') ?: $thumbnail->getConfigurationValue('maximumWidth');
         $height = $thumbnail->getConfigurationValue('height') ?: $thumbnail->getConfigurationValue('maximumHeight');
         $im = new \Imagick();
         $im->setResolution($this->getOption('resolution'), $this->getOption('resolution'));
         $im->readImage($documentFile);
         $im->setImageFormat('png');
         $im->setImageBackgroundColor('white');
         $im->setImageCompose(\Imagick::COMPOSITE_OVER);
         $im->setImageAlphaChannel(\Imagick::ALPHACHANNEL_RESET);
         $im->thumbnailImage($width, $height, true);
         $im->flattenImages();
         // Replace flattenImages in imagick 3.3.0
         // @see https://pecl.php.net/package/imagick/3.3.0RC2
         // $im->mergeImageLayers(\Imagick::LAYERMETHOD_MERGE);
         $resource = $this->resourceManager->importResourceFromContent($im->getImageBlob(), $filenameWithoutExtension . '.png');
         $im->destroy();
         $thumbnail->setResource($resource);
         $thumbnail->setWidth($width);
         $thumbnail->setHeight($height);
     } catch (\Exception $exception) {
         $filename = $thumbnail->getOriginalAsset()->getResource()->getFilename();
         $sha1 = $thumbnail->getOriginalAsset()->getResource()->getSha1();
         $message = sprintf('Unable to generate thumbnail for the given document (filename: %s, SHA1: %s)', $filename, $sha1);
         throw new Exception\NoThumbnailAvailableException($message, 1433109652, $exception);
     }
 }
Пример #2
0
 /**
  * Internal
  *
  * Flatten the image.
  */
 private function flatten()
 {
     try {
         $this->imagick = $this->imagick->flattenImages();
     } catch (\ImagickException $e) {
         throw new RuntimeException('Flatten operation failed', $e->getCode(), $e);
     }
 }
 /**
  * Crops Image.
  *
  * @since 3.5.0
  * @access public
  *
  * @param string|int $src The source file or Attachment ID.
  * @param int $src_x The start x position to crop from.
  * @param int $src_y The start y position to crop from.
  * @param int $src_w The width to crop.
  * @param int $src_h The height to crop.
  * @param int $dst_w Optional. The destination width.
  * @param int $dst_h Optional. The destination height.
  * @param boolean $src_abs Optional. If the source crop points are absolute.
  * @return boolean|WP_Error
  */
 public function crop($src_x, $src_y, $src_w, $src_h, $dst_w = null, $dst_h = null, $src_abs = false)
 {
     $ar = $src_w / $src_h;
     $dst_ar = $dst_w / $dst_h;
     if (isset($_GET['pte-fit-crop-color']) && abs($ar - $dst_ar) > 0.01) {
         PteLogger::debug(sprintf("IMAGICK - AR: '%f'\tOAR: '%f'", $ar, $dst_ar));
         // Crop the image to the correct aspect ratio...
         if ($dst_ar > $ar) {
             // constrain to the dst_h
             $tmp_dst_h = $dst_h;
             $tmp_dst_w = $dst_h * $ar;
             $tmp_dst_y = 0;
             $tmp_dst_x = $dst_w / 2 - $tmp_dst_w / 2;
         } else {
             $tmp_dst_w = $dst_w;
             $tmp_dst_h = $dst_w / $ar;
             $tmp_dst_x = 0;
             $tmp_dst_y = $dst_h / 2 - $tmp_dst_h / 2;
         }
         //$color = this::getImagickPixel( $_GET['pte-fit-crop-color'] );
         if (preg_match("/^#[a-fA-F0-9]{6}\$/", $_GET['pte-fit-crop-color'])) {
             $color = new ImagickPixel($_GET['pte-fit-crop-color']);
         }
         //else {
         //    PteLogger::debug( "setting transparent/white" );
         //    $color = new ImagickPixel( 'white' );
         //    //$color->setColorValue( Imagick::COLOR_ALPHA, 0 );
         //}
         try {
             // crop the original image
             $this->image->cropImage($src_w, $src_h, $src_x, $src_y);
             $this->image->scaleImage($tmp_dst_w, $tmp_dst_h);
             // Create a new image and then compose the old one onto it.
             $img = new Imagick();
             $img->newImage($dst_w, $dst_h, isset($color) ? $color : 'white');
             $img->setImageFormat($this->image->getImageFormat());
             if (!isset($color)) {
                 $img->setImageOpacity(0.0);
             }
             $img->compositeImage($this->image, Imagick::COMPOSITE_DEFAULT, $tmp_dst_x, $tmp_dst_y);
             $img->flattenImages();
             $this->image = $img;
         } catch (Exception $e) {
             return new WP_Error('image_crop_error', __('Image crop failed.'), $this->file);
         }
         return $this->update_size();
     }
     return parent::crop($src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs);
 }
Пример #4
0
 /**
  * Internal
  *
  * Flatten the image.
  */
 private function flatten()
 {
     /**
      * @see https://github.com/mkoppanen/imagick/issues/45
      */
     try {
         if (method_exists($this->imagick, 'mergeImageLayers') && defined('Imagick::LAYERMETHOD_UNDEFINED')) {
             $this->imagick = $this->imagick->mergeImageLayers(\Imagick::LAYERMETHOD_UNDEFINED);
         } elseif (method_exists($this->imagick, 'flattenImages')) {
             $this->imagick = $this->imagick->flattenImages();
         }
     } catch (\ImagickException $e) {
         throw new RuntimeException('Flatten operation failed', $e->getCode(), $e);
     }
 }
Пример #5
0
 /**
  * @see	\wcf\system\image\adapter\IImageAdapter::overlayImage()
  */
 public function overlayImage($file, $x, $y, $opacity)
 {
     try {
         $overlayImage = new \Imagick($file);
     } catch (\ImagickException $e) {
         throw new SystemException("Image '" . $file . "' is not readable or does not exist.");
     }
     $overlayImage->evaluateImage(\Imagick::EVALUATE_MULTIPLY, $opacity, \Imagick::CHANNEL_OPACITY);
     if ($this->imagick->getImageFormat() == 'GIF') {
         $this->imagick = $this->imagick->coalesceImages();
         do {
             $this->imagick->compositeImage($overlayImage, \Imagick::COMPOSITE_OVER, $x, $y);
         } while ($this->imagick->nextImage());
     } else {
         $this->imagick->compositeImage($overlayImage, \Imagick::COMPOSITE_OVER, $x, $y);
         $this->imagick = $this->imagick->flattenImages();
     }
 }
 /**
  * Crops Image.
  *
  * @since 3.5.0
  * @access public
  *
  * @param string|int $src The source file or Attachment ID.
  * @param int $src_x The start x position to crop from.
  * @param int $src_y The start y position to crop from.
  * @param int $src_w The width to crop.
  * @param int $src_h The height to crop.
  * @param int $dst_w Optional. The destination width.
  * @param int $dst_h Optional. The destination height.
  * @param boolean $src_abs Optional. If the source crop points are absolute.
  * @return boolean|WP_Error
  */
 public function crop($src_x, $src_y, $src_w, $src_h, $dst_w = null, $dst_h = null, $src_abs = false)
 {
     if (pte_is_crop_border_enabled($src_w, $src_h, $dst_w, $dst_h)) {
         // Crop the image to the correct aspect ratio...
         $ar = $src_w / $src_h;
         $dst_ar = $dst_w / $dst_h;
         if ($dst_ar > $ar) {
             // constrain to the dst_h
             $tmp_dst_h = $dst_h;
             $tmp_dst_w = $dst_h * $ar;
             $tmp_dst_y = 0;
             $tmp_dst_x = $dst_w / 2 - $tmp_dst_w / 2;
         } else {
             $tmp_dst_w = $dst_w;
             $tmp_dst_h = $dst_w / $ar;
             $tmp_dst_x = 0;
             $tmp_dst_y = $dst_h / 2 - $tmp_dst_h / 2;
         }
         if (pte_is_crop_border_opaque()) {
             $color = new ImagickPixel($_GET['pte-fit-crop-color']);
         }
         try {
             // crop the original image
             $this->image->cropImage($src_w, $src_h, $src_x, $src_y);
             $this->image->scaleImage($tmp_dst_w, $tmp_dst_h);
             // Create a new image and then compose the old one onto it.
             $img = new Imagick();
             $img->newImage($dst_w, $dst_h, isset($color) ? $color : 'white');
             $img->setImageFormat($this->image->getImageFormat());
             if (!isset($color)) {
                 $img->setImageOpacity(0.0);
             }
             $img->compositeImage($this->image, Imagick::COMPOSITE_DEFAULT, $tmp_dst_x, $tmp_dst_y);
             $img->flattenImages();
             $this->image = $img;
         } catch (Exception $e) {
             return new WP_Error('image_crop_error', __('Image crop failed.'), $this->file);
         }
         return $this->update_size();
     }
     return parent::crop($src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs);
 }
Пример #7
0
 /**
  * (non-PHPdoc)
  * @see Imagine\ImageInterface::paste()
  */
 public function paste(ImageInterface $image, PointInterface $start)
 {
     if (!$image instanceof self) {
         throw new InvalidArgumentException(sprintf('Imagick\\Image can ' . 'only paste() Imagick\\Image instances, %s given', get_class($image)));
     }
     if (!$this->getSize()->contains($image->getSize(), $start)) {
         throw new OutOfBoundsException('Cannot paste image of the given size at the specified ' . 'position, as it moves outside of the current image\'s box');
     }
     try {
         $this->imagick->compositeImage($image->imagick, \Imagick::COMPOSITE_DEFAULT, $start->getX(), $start->getY());
     } catch (\ImagickException $e) {
         throw new RuntimeException('Paste operation failed', $e->getCode(), $e);
     }
     try {
         $this->imagick->flattenImages();
     } catch (\ImagickException $e) {
         throw new RuntimeException('Paste operation failed', $e->getCode(), $e);
     }
     return $this;
 }
 /**
  * Prepare the image for output, scaling and flattening as required
  *
  * @since 2.10
  * @uses self::$image updates the image in this Imagick object
  *
  * @param	integer	zero or new width
  * @param	integer	zero or new height
  * @param	boolean	proportional fit (true) or exact fit (false)
  * @param	string	output MIME type
  * @param	integer	compression quality; 1 - 100
  *
  * @return void
  */
 private static function _prepare_image($width, $height, $best_fit, $type, $quality)
 {
     if (is_callable(array(self::$image, 'scaleImage'))) {
         if (0 < $width && 0 < $height) {
             // Both are set; use them as-is
             self::$image->scaleImage($width, $height, $best_fit);
         } elseif (0 < $width || 0 < $height) {
             // One is set; scale the other one proportionally if reducing
             $image_size = self::$image->getImageGeometry();
             if ($width && isset($image_size['width']) && $width < $image_size['width']) {
                 self::$image->scaleImage($width, 0);
             } elseif ($height && isset($image_size['height']) && $height < $image_size['height']) {
                 self::$image->scaleImage(0, $height);
             }
         } else {
             // Neither is specified, apply defaults
             self::$image->scaleImage(150, 0);
         }
     }
     if (0 < $quality && 101 > $quality) {
         if ('image/jpeg' == $type) {
             self::$image->setImageCompressionQuality($quality);
             self::$image->setImageCompression(imagick::COMPRESSION_JPEG);
         } else {
             self::$image->setImageCompressionQuality($quality);
         }
     }
     if ('image/jpeg' == $type) {
         if (is_callable(array(self::$image, 'setImageBackgroundColor'))) {
             self::$image->setImageBackgroundColor('white');
         }
         if (is_callable(array(self::$image, 'mergeImageLayers'))) {
             self::$image = self::$image->mergeImageLayers(imagick::LAYERMETHOD_FLATTEN);
         } elseif (is_callable(array(self::$image, 'flattenImages'))) {
             self::$image = self::$image->flattenImages();
         }
     }
 }
Пример #9
0
        $watermarkHeight = $watermark->getImageHeight();
        // Get original image sizes
        $imageWidth = $original->getImageWidth();
        $imageHeight = $original->getImageHeight();
        // Merge watermark in tiling mode
        for ($x = $initialX;; $x += $watermarkWidth + (int) $originY) {
            for ($y = $initialY;; $y += $watermarkHeight + (int) $originX) {
                $original->compositeImage($watermark, Imagick::COMPOSITE_DEFAULT, $x, $y);
                if ($y > $imageHeight) {
                    break;
                }
            }
            if ($x > $imageWidth) {
                break;
            }
        }
    } else {
        // Merge watermark in normal mode
        $original->compositeImage($watermark, Imagick::COMPOSITE_DEFAULT, $originX, $originY);
    }
    // Make flat image
    $original->flattenImages();
    // Make filename and filedir
    $file_name = make_filename($originalImagePath, 'png');
    $file_dir = get_download_filedir($file_name);
    // Save image
    $original->setImageFormat('png');
    $original->writeImage($file_dir);
    // Send image name to user
    send_filename($file_name);
}
Пример #10
0
 /**
  * Image conversion abstraction.
  *
  * @param string $source
  * @param array $size
  * @return Imagick
  */
 protected function _convert($source, $size)
 {
     extract($size);
     $im = new Imagick();
     $js = 0;
     $hint = max($tw, $th) * $js;
     if ($hint > 0 && $hint < $sw && $hint < $sh) {
         if (pathinfo($source, PATHINFO_EXTENSION) === 'jpg') {
             $im->setOption('jpeg:size', sprintf('%dx%d', $hint, $hint));
         }
     }
     $im->readImage($source);
     if ($im->getNumberImages() > 1) {
         $im->flattenImages();
     }
     $colorspace = $im->getImageColorSpace();
     if ($colorspace !== Imagick::COLORSPACE_RGB && $colorspace !== Imagick::COLORSPACE_SRGB) {
         $im->setImageColorSpace(Imagick::COLORSPACE_SRGB);
     }
     if ($im->getImageMatte()) {
         $im->setImageMatte(false);
     }
     if ($this->doesTrimming()) {
         $im->cropImage($sw, $sh, $sx, $sy);
     }
     if ($this->doesResampling()) {
         $im->resizeImage($tw, $th, Imagick::FILTER_LANCZOS, 0.9, true);
     }
     $im->stripImage();
     $degrees = $this->getRotation();
     if ($degrees) {
         $bgcolor = $this->getBgColor();
         $bg = sprintf('rgb(%d,%d,%d)', $bgcolor[0], $bgcolor[1], $bgcolor[2]);
         $im->rotateImage(new ImagickPixel($bg), $degrees);
     }
     if ($this->isPng()) {
         $im->setFormat('PNG');
     } else {
         $im->setFormat('JPEG');
         if ($this->getQuality()) {
             $im->setCompressionQuality($this->getQuality());
         }
     }
     return $im;
 }
Пример #11
0
    private function createThumb($src, $dist, $new_w, $new_h, $resize_type, $watermark) {
        if (file_exists($dist)) {
            if (!is_writable($dist)) { return false; }
            unlink($dist);
        }
        
        if (!in_array($resize_type, array('exact', 'auto', 'crop', 'portrait', 'landscape'))) {
            $resize_type = 'auto';
        }
        
        if (!in_array($watermark, array('lt', 'lc', 'lb', 'rt', 'rc', 'rb', 'tc', 'c', 'bc')) && $watermark !== false) {
            $watermark = 'rb';
        }
        
        if ((int)$new_w) {
            if (
                ($this->w < $new_w && $this->h < $new_h) || 
                ($resize_type == 'portrait' && $this->h < $new_h) || 
                ($resize_type == 'landscape' && $this->w < $new_w)
            ) {
                copy($src, $dist);
            } else {
                $new_size = $this->getNewImageSize($new_w, $new_h, $resize_type);
                
                if ($this->Imagick === true) {
                    $image = new Imagick($src);
                    
                    switch ($resize_type) {
                        case 'auto':
                            if ($this->ext == 'gif'){
                                foreach ($image as $img) {
                                    $img->resizeImage($new_w, $new_h, Imagick::FILTER_LANCZOS, 1, true);
                                    $img->setImagePage($img->getImageWidth(), $img->getImageHeight(), 0, 0);
                                }
                            } else {
                                $image->resizeImage($new_w, $new_h, Imagick::FILTER_LANCZOS, 1, true);
                            }
                            
                            break;
                        case 'portrait':
                            if ($this->ext == 'gif'){
                                foreach ($image as $img) {
                                    $img->resizeImage(0, $new_h, Imagick::FILTER_LANCZOS, 1);
                                    $img->setImagePage($img->getImageWidth(), $img->getImageHeight(), 0, 0);
                                }
                            } else {
                                $image->resizeImage(0, $new_h, Imagick::FILTER_LANCZOS, 1);
                            }
                            break;
                        case 'landscape':
                            if ($this->ext == 'gif'){
                                foreach ($image as $img) {
                                    $img->resizeImage($new_w, 0, Imagick::FILTER_LANCZOS, 1);
                                    $img->setImagePage($img->getImageWidth(), $img->getImageHeight(), 0, 0);
                                }
                            } else {
                                $image->resizeImage($new_w, 0, Imagick::FILTER_LANCZOS, 1);
                            }
                            break;
                        case 'exact':
                            if ($this->ext == 'gif'){
                                foreach ($image as $img) {
                                    $img->resizeImage($new_w, $new_h, Imagick::FILTER_LANCZOS, 1);
                                    $img->setImagePage($img->getImageWidth(), $img->getImageHeight(), 0, 0);
                                }
                            } else {
                                $image->resizeImage($new_w, $new_h, Imagick::FILTER_LANCZOS, 1);
                            }
                            break;
                        case 'crop':
                            if ($this->ext == 'gif') {
                                foreach ($image as $img) {
                                    $img->cropThumbnailImage($new_w, $new_h);
                                    $img->setImagePage($img->getImageWidth(), $img->getImageHeight(), 0, 0);
                                }
                            } else {
                                $image->cropThumbnailImage($new_w, $new_h);
                            }
                            break;
                    }
                    
                    $image->setImageCompressionQuality($this->quality);
                    
                    if ($this->ext == 'jpg') {
                        $image->setImageBackgroundColor('white');
                        $image->flattenImages();
                        $image = $image->flattenImages();
                        $image->setImageCompression(Imagick::COMPRESSION_JPEG);
                    }
                    
                    $image->setImageFormat($this->ext);
                    
                    if ($this->ext == 'gif') {
                        $image->writeimages($dist);
                    } else {
                        $image->writeimage($dist);
                    }

                    $image->destroy();
                } else {
                    $this->new_img = imagecreatetruecolor($new_size['w'], $new_size['h']);

                    imagecopyresampled($this->new_img, $this->old_img, 0, 0, 0, 0, $new_size['w'], $new_size['h'], $this->w, $this->h);

                    if ($resize_type == 'crop') {
                        $this->crop($new_size['w'], $new_size['h'], $new_w, $new_h);
                    }

                    if ($this->ext != 'gif' || $this->Imagick === true) {
                        $this->saveImage($dist, $this->ext);
                    } else {
                        $gif_resize = new gifresizer();
                        $gif_resize->resize($src, $dist, $new_w, $new_h);
                    }
                }
            }
            
            if (!empty($watermark)) {
                self::addWatermark($dist, false, $watermark);
            }
        } else if ($new_w == 'copy') {
            copy($src, $dist);
        }
    }
Пример #12
0
 function create_thumbnail($filename, $save2disk = true, $resize_type = 0)
 {
     $filename = $this->basename($filename);
     if ($this->is_image($this->mmhclass->info->root_path . $this->mmhclass->info->config['upload_path'] . $filename) == true) {
         $extension = $this->file_extension($filename);
         $thumbnail = $this->thumbnail_name($filename);
         if ($save2disk == true) {
             // Seemed easier to build the image resize upload
             // option into the already established thumbnail function
             // instead of waisting time trying to chop it up for new one.
             if ($resize_type > 0 && $resize_type <= 8) {
                 $thumbnail = $filename;
                 $this->mmhclass->info->config['advanced_thumbnails'] = false;
                 $size_values = array(1 => array("w" => 100, "h" => 75), 2 => array("w" => 150, "h" => 112), 3 => array("w" => 320, "h" => 240), 4 => array("w" => 640, "h" => 480), 5 => array("w" => 800, "h" => 600), 6 => array("w" => 1024, "h" => 768), 7 => array("w" => 1280, "h" => 1024), 8 => array("w" => 1600, "h" => 1200));
                 $thumbnail_size = $size_values[$resize_type];
             } else {
                 $thumbnail_size = $this->scale($filename, $this->mmhclass->info->config['thumbnail_width'], $this->mmhclass->info->config['thumbnail_height']);
             }
             if ($this->manipulator == "imagick") {
                 // New Design of Advanced Thumbnails created by: IcyTexx - http://www.hostili.com
                 // Classic Design of Advanced Thumbnails created by: Mihalism Technologies - http://www.mihalism.net
                 $canvas = new Imagick();
                 $athumbnail = new Imagick();
                 $imagick_version = $canvas->getVersion();
                 // Imagick needs to start giving real version number, not build number.
                 $new_thumbnails = version_compare($imagick_version['versionNumber'], "1621", ">=") == true ? true : false;
                 $athumbnail->readImage("{$this->mmhclass->info->root_path}{$this->mmhclass->info->config['upload_path']}{$filename}[0]");
                 $athumbnail->flattenImages();
                 $athumbnail->orgImageHeight = $athumbnail->getImageHeight();
                 $athumbnail->orgImageWidth = $athumbnail->getImageWidth();
                 $athumbnail->orgImageSize = $athumbnail->getImageLength();
                 $athumbnail->thumbnailImage($thumbnail_size['w'], $thumbnail_size['h']);
                 if ($this->mmhclass->info->config['advanced_thumbnails'] == true) {
                     $thumbnail_filesize = $this->format_filesize($athumbnail->orgImageSize, true);
                     $resobar_filesize = $thumbnail_filesize['f'] < 0 || $thumbnail_filesize['c'] > 9 ? $this->mmhclass->lang['5454'] : sprintf("%s%s", round($thumbnail_filesize['f']), $this->mmhclass->lang['7071'][$thumbnail_filesize['c']]);
                     if ($new_thumbnails == true) {
                         $textdraw = new ImagickDraw();
                         $textdrawborder = new ImagickDraw();
                         if ($athumbnail->getImageWidth() > 113) {
                             $textdraw->setFillColor(new ImagickPixel("white"));
                             $textdraw->setFontSize(9);
                             $textdraw->setFont("{$mmhclass->info->root_path}css/fonts/sf_fedora_titles.ttf");
                             $textdraw->setFontWeight(900);
                             $textdraw->setGravity(8);
                             $textdraw->setTextKerning(1);
                             $textdraw->setTextAntialias(false);
                             $textdrawborder->setFillColor(new ImagickPixel("black"));
                             $textdrawborder->setFontSize(9);
                             $textdrawborder->setFont("{$mmhclass->info->root_path}css/fonts/sf_fedora_titles.ttf");
                             $textdrawborder->setFontWeight(900);
                             $textdrawborder->setGravity(8);
                             $textdrawborder->setTextKerning(1);
                             $textdrawborder->setTextAntialias(false);
                             $array_x = array("-1", "0", "1", "1", "1", "0", "-1", "-1");
                             $array_y = array("-1", "-1", "-1", "0", "1", "1", "1", "0");
                             foreach ($array_x as $key => $value) {
                                 $athumbnail->annotateImage($textdrawborder, $value, 3 - $array_y[$key], 0, "{$athumbnail->orgImageWidth}x{$athumbnail->orgImageHeight} - {$resobar_filesize}");
                             }
                             $athumbnail->annotateImage($textdraw, 0, 3, 0, "{}x{$athumbnail->orgImageHeight} - {$resobar_filesize}");
                         }
                     } else {
                         $transback = new Imagick();
                         $canvasdraw = new ImagickDraw();
                         $canvas->newImage($athumbnail->getImageWidth(), $athumbnail->getImageHeight() + 12, new ImagickPixel("black"));
                         $transback->newImage($canvas->getImageWidth(), $canvas->getImageHeight() - 12, new ImagickPixel("white"));
                         $canvas->compositeImage($transback, 40, 0, 0);
                         $canvasdraw->setFillColor(new ImagickPixel("white"));
                         $canvasdraw->setGravity(8);
                         $canvasdraw->setFontSize(10);
                         $canvasdraw->setFontWeight(900);
                         $canvasdraw->setFont("AvantGarde-Demi");
                         $canvas->annotateImage($canvasdraw, 0, 0, 0, "{$athumbnail->orgImageWidth}x{$athumbnail->orgImageHeight} - {$resobar_filesize}");
                         $canvas->compositeImage($athumbnail, 40, 0, 0);
                         $athumbnail = $canvas->clone();
                     }
                 }
                 if ($this->mmhclass->info->config['thumbnail_type'] == "jpeg") {
                     $athumbnail->setImageFormat("jpeg");
                     $athumbnail->setImageCompression(9);
                 } else {
                     $athumbnail->setImageFormat("png");
                 }
                 $athumbnail->writeImage($this->mmhclass->info->root_path . $this->mmhclass->info->config['upload_path'] . $thumbnail);
             } else {
                 // I hate GD. Piece of crap supports nothing. NOTHING!
                 if (in_array($extension, array("png", "gif", "jpg", "jpeg")) == true) {
                     $function_extension = str_replace("jpg", "jpeg", $extension);
                     $image_function = "imagecreatefrom{$function_extension}";
                     $image = $image_function($this->mmhclass->info->root_path . $this->mmhclass->info->config['upload_path'] . $filename);
                     $imageinfo = $this->get_image_info($this->mmhclass->info->root_path . $this->mmhclass->info->config['upload_path'] . $this->basename($filename));
                     $thumbnail_image = imagecreatetruecolor($thumbnail_size['w'], $thumbnail_size['h']);
                     $index = imagecolortransparent($thumbnail_image);
                     if ($index < 0) {
                         $white = imagecolorallocate($thumbnail_image, 255, 255, 255);
                         imagefill($thumbnail_image, 0, 0, $white);
                     }
                     imagecopyresampled($thumbnail_image, $image, 0, 0, 0, 0, $thumbnail_size['w'], $thumbnail_size['h'], $imageinfo['width'], $imageinfo['height']);
                     $image_savefunction = sprintf("image%s", $this->mmhclass->info->config['thumbnail_type'] == "jpeg" ? "jpeg" : "png");
                     $image_savefunction($thumbnail_image, $this->mmhclass->info->root_path . $this->mmhclass->info->config['upload_path'] . $thumbnail);
                     chmod($this->mmhclass->info->root_path . $this->mmhclass->info->config['upload_path'] . $thumbnail, 0644);
                     imagedestroy($image);
                     imagedestroy($thumbnail_image);
                 } else {
                     trigger_error("Image format not supported by GD", E_USER_ERROR);
                 }
             }
             chmod($this->mmhclass->info->root_path . $this->mmhclass->info->config['upload_path'] . $thumbnail, 0644);
         } else {
             readfile($this->mmhclass->info->root_path . $this->mmhclass->info->config['upload_path'] . $thumbnail);
         }
     }
 }
Пример #13
0
/**
 * Clip a part from an image and optionally, resize it.
 *
 * This function can be used to clip a part of an image. You can specifiy
 * width and/or a height to which to scale the clipped image.
 *
 * Below, you see an image of the way in which a clip is defined by the
 * function parameters. $clip_x, $clip_y, $clip_w and $clip_h.
 * <code>
 * +------------------------------------------+
 * |                       ^                  |
 * |                       |                  |
 * |                     clip_y               |
 * |                       |                  |
 * |                       v                  |
 * |            +-------------------+   ^     |
 * |            |                   |   |     |
 * |<--clip_x-->|                   |   |     |
 * |            |      CLIPPED      |   |     |
 * |            |       IMAGE       | clip_h  |
 * |            |                   |   |     |
 * |            |                   |   |     |
 * |            +-------------------+   v     |
 * |                                          |
 * |            <-------clip_w------>         |
 * |                                          |
 * +------------------------------------------+
 * </code>
 *
 * @param string $image
 *     The raw binary image data.
 *
 * @param integer $clip_x
 *     The X-offset for the clip, where 0 indicates the left of the image.
 * @param integer $clip_y
 *     The Y-offset for the clip, where 0 indicates the top of the image.
 * @param integer $clip_w
 *     The width of the clip to take out of the image.
 * @param integer $clip_h
 *     The height of the clip to take out of the image.
 *
 * @param integer $dst_w
 *     The width for the created clip image in pixels.
 *     Use NULL or 0 (zero) to indicate that the width should be
 *     the same as the $clip_w parameter.
 * @param integer $dst_h
 *     The height for the created clip image in pixels.
 *     Use NULL or 0 (zero) to indicate that the height should be
 *     the same as the $clip_h parameter.
 *
 * @param string $method
 *     The method to use for scaling the image. By default, this function
 *     will try to autodetect a working method. Providing a $method parameter
 *     is mostly useful for debugging purposes. Available methods (in the
 *     order in which they are probed in the code) are:
 *     - imagick : using the ImageMagick library (requires extension "imagick")
 *     - gd      : using the GD library (requires extension "gd")
 *     - convert : using the ImageMagick "convert" tool (requires the
 *                 ImageMagick package to be installed on the server and does
 *                 not work in combination with some PHP safety restrictions).
 *
 * @return mixed
 *     FALSE is returned in case creating the clip image failed. The function
 *     {@link phorum_api_error_message()} can be used to retrieve information
 *     about the error that occurred.
 *
 *     An array is returned in case creating the clip image did work.
 *     This array contains the following fields:
 *     - image    : The scaled down image. NULL if no scaling was needed.
 *     - method   : The method that was used to create the thumbnail.
 *     - cur_w    : The width of the original $image.
 *     - cur_h    : The height of the original $image.
 *     - cur_mime : The MIME type of the original $image.
 *     - new_w    : The width of the scaled down image.
 *     - new_h    : The height of the scaled down image.
 *     - new_mime : The MIME type of the scaled down image,
 */
function phorum_api_image_clip($image, $clip_x = 0, $clip_y = 0, $clip_w = NULL, $clip_h = NULL, $dst_w = NULL, $dst_h = NULL, $method = NULL)
{
    global $PHORUM;
    settype($clip_x, 'int');
    settype($clip_y, 'int');
    settype($clip_w, 'int');
    settype($clip_h, 'int');
    settype($dst_w, 'int');
    settype($dst_h, 'int');
    // Reset error storage.
    $PHORUM['API']['errno'] = NULL;
    $PHORUM['API']['error'] = NULL;
    $error = NULL;
    // Initialize the return array.
    $img = array('image' => NULL, 'new_mime' => NULL);
    // Retrieve image info.
    $image_info = phorum_api_image_info($image);
    if ($image_info === FALSE) {
        return FALSE;
    }
    // Derive a name for the image type.
    switch ($image_info['type']) {
        case IMAGETYPE_JPEG:
            $type = 'jpeg';
            break;
        case IMAGETYPE_GIF:
            $type = 'gif';
            break;
        case IMAGETYPE_PNG:
            $type = 'png';
            break;
        default:
            $type = 'unknown';
            // should not occur
    }
    // The clip width and height are inherited from the image
    // width and height, unless they are set.
    if (empty($clip_w)) {
        $clip_w = $image_info['width'] - $clip_x;
    }
    if (empty($clip_h)) {
        $clip_h = $image_info['height'] - $clip_y;
    }
    // The target image width and height are inherited from the clip
    // width and height, unless they are set.
    if (empty($dst_w)) {
        $dst_w = $clip_w;
    }
    if (empty($dst_h)) {
        $dst_h = $clip_h;
    }
    // Add the image data to the return array.
    $img['cur_w'] = $image_info['width'];
    $img['cur_h'] = $image_info['height'];
    $img['new_w'] = $dst_w;
    $img['new_h'] = $dst_h;
    $img['cur_mime'] = $img['new_mime'] = $image_info['mime'];
    // Check if the requested clip fits the source image size.
    if ($clip_x + $clip_w > $img['cur_w']) {
        return phorum_api_error(PHROM_ERRNO_ERROR, "The clip X offset {$clip_x} + clip width {$clip_w} exceeds " . "the source image width {$img['cur_w']}");
    }
    if ($clip_y + $clip_h > $img['cur_h']) {
        return phorum_api_error(PHROM_ERRNO_ERROR, "The clip Y offset {$clip_y} + clip height {$clip_h} exceeds " . "the source image height {$img['cur_h']}");
    }
    // -----------------------------------------------------------------
    // Try to use the imagick library tools
    // -----------------------------------------------------------------
    if (($method === NULL || $method == 'imagick') && extension_loaded('imagick') && class_exists('Imagick')) {
        $method = NULL;
        $imagick = new Imagick();
        $imagick->readImageBlob($image);
        $imagick->flattenImages();
        $tmp = new Imagick();
        $tmp->newPseudoImage($img['cur_w'], $img['cur_h'], 'xc:white');
        $tmp->compositeImage($imagick, imagick::COMPOSITE_OVER, 0, 0);
        $imagick = $tmp;
        $imagick->cropImage($clip_w, $clip_h, $clip_x, $clip_y);
        $imagick->thumbnailImage($dst_w, $dst_h, FALSE);
        $imagick->setImagePage($clip_w, $clip_h, 0, 0);
        $imagick->setFormat("jpg");
        $img['image'] = $imagick->getImagesBlob();
        $img['new_mime'] = 'image/jpeg';
        $img['method'] = 'imagick';
        return $img;
    }
    // -----------------------------------------------------------------
    // Try to use the GD library tools
    // -----------------------------------------------------------------
    if (($method === NULL || $method == 'gd') && extension_loaded('gd') && function_exists('gd_info')) {
        // We need gd_info() to check whether GD has the required
        // image support for the type of image that we are handling.
        $gd = gd_info();
        // We always need JPEG support for the scaled down image.
        if (empty($gd['JPG Support']) && empty($gd['JPEG Support'])) {
            $error = "GD: no JPEG support available for processing images";
        } elseif ($type == 'gif' && empty($gd['GIF Read Support']) || $type == 'jpeg' && (empty($gd['JPG Support']) && empty($gd['JPEG Support'])) || $type == 'png' && empty($gd['PNG Support'])) {
            $error = "GD: no support available for image type \"{$type}\"";
        } else {
            // Create a GD image handler based on the image data.
            // imagecreatefromstring() spawns PHP warnings if the file cannot
            // be processed. We do not care to see that in the event logging,
            // so if event logging is loaded, we suspend it here.
            // Instead, we catch error output and try to mangle it into a
            // usable error message.
            if (defined('EVENT_LOGGING')) {
                phorum_mod_event_logging_suspend();
            }
            ob_start();
            $original = @imagecreatefromstring($image);
            $error = ob_get_contents();
            ob_end_clean();
            $error = trim(preg_replace('!(^(?:\\w+:\\s*).*?:|in /.*$)!', '', trim($error)));
            if (defined('EVENT_LOGGING')) {
                phorum_mod_event_logging_resume();
            }
            if (!$original) {
                if ($error == '') {
                    $error = "GD: Cannot process the {$type} image using GD";
                } else {
                    $error = 'GD: ' . $error;
                }
            } else {
                // Create the scaled image.
                $scaled = imagecreatetruecolor($dst_w, $dst_h);
                // Fill the image to have a background for transparent pixels.
                $white = imagecolorallocate($scaled, 255, 255, 255);
                imagefill($scaled, 0, 0, $white);
                // Scale the image.
                imagecopyresampled($scaled, $original, 0, 0, $clip_x, $clip_y, $dst_w, $dst_h, $clip_w, $clip_h);
                // Create the jpeg output data for the scaled image.
                ob_start();
                imagejpeg($scaled);
                $image = ob_get_contents();
                $size = ob_get_length();
                ob_end_clean();
                imagedestroy($original);
                imagedestroy($scaled);
                $img['image'] = $image;
                $img['new_mime'] = 'image/jpeg';
                $img['method'] = 'gd';
                return $img;
            }
        }
    }
    // -----------------------------------------------------------------
    // Try to use the ImageMagick "convert" tool
    // -----------------------------------------------------------------
    if ($method === NULL || $method == 'convert') {
        // Try to find the "convert" utility.
        // First, check if it is configured in the Phorum settings.
        $convert = NULL;
        if (isset($PHORUM['imagemagick_convert_path'])) {
            $path = $PHORUM['imagemagick_convert_path'];
            if (is_executable($path)) {
                $convert = $path;
            }
        }
        // Not found? Then simply use "convert" and hope that it
        // can be found in the OS' path.
        if ($convert === NULL) {
            $convert = 'convert';
        }
        // Build the command line.
        $cmd = escapeshellcmd($convert) . ' ' . '- ' . '-background white -flatten ' . "-crop {$clip_w}x{$clip_h}+{$clip_x}+{$clip_y} " . '+repage ' . '-thumbnail ' . $dst_w . 'x' . $dst_h . '\\! ' . 'jpeg:-';
        // Run the command.
        $descriptors = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
        $process = proc_open($cmd, $descriptors, $pipes);
        if ($process == FALSE) {
            $error = 'Failed to execute "convert".';
        } else {
            // Feed convert the image data on STDIN.
            fwrite($pipes[0], $image);
            fclose($pipes[0]);
            // Read the scaled image from STDOUT.
            $scaled = stream_get_contents($pipes[1]);
            fclose($pipes[1]);
            // Read errors.
            $errors = trim(stream_get_contents($pipes[2]));
            fclose($pipes[2]);
            $exit = proc_close($process);
            if ($exit == 0) {
                $img['image'] = $scaled;
                $img['new_mime'] = 'image/jpeg';
                $img['method'] = 'convert';
                return $img;
            }
            // Some error occurred.
            if ($errors == '') {
                $error = 'Got exit code ' . $exit . ' from "convert".';
            } else {
                $error = $errors;
            }
        }
    }
    // -----------------------------------------------------------------
    // Safety nets.
    // -----------------------------------------------------------------
    // Return error if one was set.
    if ($error) {
        return phorum_api_error(PHORUM_ERRNO_ERROR, $error);
    }
    // Catch illegal methods
    if ($method !== NULL) {
        return phorum_api_error(PHORUM_ERRNO_ERROR, 'Illegal scaling method: ' . $method);
    }
    // If we get here, then we were totally out of luck.
    return phorum_api_error(PHORUM_ERRNO_ERROR, 'No working image scaling method found');
}
 protected function create_scaled_image($file_name, $options)
 {
     $file_path = $this->options['upload_dir'] . $file_name;
     $new_file_path = $options['upload_dir'] . $file_name;
     if (extension_loaded('imagick')) {
         // Special Postscript case
         if ($this->is_ps_file($file_name)) {
             try {
                 $im = new \Imagick($file_path);
                 $im->flattenImages();
                 $im->setImageFormat('png');
                 $file_name .= '.png';
                 $file_path .= '.png';
                 $new_file_path .= '.png';
                 $im->writeImage($file_path);
             } catch (\ImagickException $e) {
                 return false;
             }
         }
     }
     list($img_width, $img_height) = @getimagesize($file_path);
     if (!$img_width || !$img_height) {
         return false;
     }
     $scale = min($options['max_width'] / $img_width, $options['max_height'] / $img_height);
     if ($scale >= 1) {
         if ($file_path !== $new_file_path) {
             return copy($file_path, $new_file_path);
         }
         return true;
     }
     $new_width = $img_width * $scale;
     $new_height = $img_height * $scale;
     $new_img = @imagecreatetruecolor($new_width, $new_height);
     switch (strtolower(substr(strrchr($file_name, '.'), 1))) {
         case 'jpg':
         case 'jpeg':
             $src_img = @imagecreatefromjpeg($file_path);
             $write_image = 'imagejpeg';
             $image_quality = isset($options['jpeg_quality']) ? $options['jpeg_quality'] : 75;
             break;
         case 'gif':
             @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
             $src_img = @imagecreatefromgif($file_path);
             $write_image = 'imagegif';
             $image_quality = null;
             break;
         case 'png':
             @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
             @imagealphablending($new_img, false);
             @imagesavealpha($new_img, true);
             $src_img = @imagecreatefrompng($file_path);
             $write_image = 'imagepng';
             $image_quality = isset($options['png_quality']) ? $options['png_quality'] : 9;
             break;
         default:
             $src_img = null;
     }
     $success = $src_img && @imagecopyresampled($new_img, $src_img, 0, 0, 0, 0, $new_width, $new_height, $img_width, $img_height) && $write_image($new_img, $new_file_path, $image_quality);
     // Free up memory (imagedestroy does not delete files):
     @imagedestroy($src_img);
     @imagedestroy($new_img);
     return $success;
 }
Пример #15
0
$site = addhttp($site);
$blankPhone = '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';
$image = file_get_contents("https://www.googleapis.com/pagespeedonline/v1/runPagespeed?url={$site}&screenshot=true&strategy=mobile");
$image = json_decode($image, true);
$image = $image['screenshot']['data'];
$image = str_replace(array('_', '-'), array('/', '+'), $image);
$imageBlob = base64_decode($image);
$im = new Imagick();
$im->readImageBlob($imageBlob);
$im->setImageFormat('png');
$im->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
$im->setImageMatte(true);
$controlPoints = array(0, 0, 100, 127, 320, 0, 392, 8, 0, 533, 348, 577, 320, 533, 658, 433);
$im->distortImage(Imagick::DISTORTION_PERSPECTIVE, $controlPoints, true);
$output = new Imagick();
$phoneBlob = base64_decode($blankPhone);
$output->readImageBlob($phoneBlob);
$output->setImageFormat('png');
$output->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
$output->compositeimage($im->getimage(), $output->getImageCompose(), 130, 88);
$output->flattenImages();
function addhttp($url)
{
    if (!preg_match("~^(?:f|ht)tps?://~i", $url)) {
        $url = "http://" . $url;
    }
    return $url;
}
//header("Content-Type: image/png");
//echo $output;
echo '<img class="headerPic" src="data:image/jpg;base64,' . base64_encode($output) . '" alt="" />';