自动在浏览器中裁剪图像

时间:2022-04-03 17:15:07

How can I crop an image automatically through the upload process? Is there php function to do that?

如何通过上传过程自动裁剪图像?有没有PHP功能呢?

I want my webpage to display the images with the same dimension from various dimension of the original images by cropping it.

我希望我的网页通过裁剪来显示原始图像的各个维度具有相同尺寸的图像。

Or any idea?

或者任何想法?

2 个解决方案

#1


1  

Say this as max_size.php

把它称为max_size.php

<?php header('Content-type: image/jpeg');
function resampleimage($maxsize, $sourcefile, $imgcomp=0){
$g_imgcomp=100-$imgcomp;
    if(file_exists($sourcefile)){
    $g_is=getimagesize($sourcefile);
        if($g_is[0] <= $maxsize && $g_is[1] <= $maxsize){
            $new_width=$g_is[0];
            $new_height=$g_is[1];
        } else {
            $w_adjust = ($maxsize / $g_is[0]);
            $h_adjust = ($maxsize / $g_is[1]);
      if($w_adjust <= $h_adjust){
          $new_width=($g_is[0]*$w_adjust);
          $new_height=($g_is[1]*$w_adjust);
      } else {
          $new_width=($g_is[0]*$h_adjust);
          $new_height=($g_is[1]*$h_adjust);
      }
    }
    $image_type = strtolower(strrchr($sourcefile, "."));

    switch($image_type) {
      case '.jpg':
         $img_src = imagecreatefromjpeg($sourcefile);
         break;
      case '.jpeg':
         $img_src = imagecreatefromjpeg($sourcefile);
         break;
      case '.png':
         $img_src = imagecreatefrompng($sourcefile);
         break;
      case '.gif':
         $img_src = imagecreatefromgif($sourcefile);
         break;
      default:
         echo("Error Invalid Image Type");
         die;
         break;
   }
  $img_dst=imagecreatetruecolor($new_width,$new_height);
  imagecopyresampled($img_dst, $img_src, 0, 0, 0, 0, $new_width, $new_height, $g_is[0], $g_is[1]);
  imagejpeg($img_dst);
  imagedestroy($img_dst);
  return true;
  } else {
  return false;
  }
}
resampleimage($_GET['maxsize'], $_GET['source']);
?>

In the page where you have image

在您有图像的页面中

<img id="img" src="max_size.php?maxsize=152&source=[some image path]" />

#2


2  

Automatic cropping would be difficult without knowing where is the subject. Maybe you can try to get an inner centered rectangle, like in the picture:

如果不知道主题在哪里,自动裁剪将很困难。也许你可以尝试获得一个内部居中的矩形,如图所示:

自动在浏览器中裁剪图像

The first thing to do is find the original image dimensions and file type. You should not trust the image extension and instead use getimagesize for that. Despite the name getimagesize not only returns the size but also the file type.

首先要做的是找到原始图像尺寸和文件类型。你不应该相信图像扩展,而是使用getimagesize。尽管名称getimagesize不仅返回大小,还返回文件类型。

//width is at index 0, height at index 1, mime type at ['mime'] key
$original = getimagesize($filename); 

Then you should build an internal PHP data structure to hold the source image in memory, so you can manipulate it, using imagecreatefromjpeg or imagecreatefrompng or imagecreatefromgif, depending on the image type. For instance:

然后你应该构建一个内部PHP数据结构来将源图像保存在内存中,这样你就可以使用imagecreatefromjpeg或imagecreatefrompng或imagecreatefromgif来操作它,具体取决于图像类型。例如:

$srcImage = imagecreatefromjpeg($filename);

Next, you should allocate another data structure to hold the destination image. In this case we don't have an image to start with, so I allocate an empty image.

接下来,您应该分配另一个数据结构来保存目标图像。在这种情况下,我们没有图像开头,所以我分配一个空图像。

$dstImage = imagecreatetruecolor($newWidth, $newHeight);

Next, you should copy a portion of the original image to the destination image. If you don't want to resize, use imagecopy, otherwise if you want to crop and resize you can consider imagecopyresampled.

接下来,您应该将原始图像的一部分复制到目标图像。如果您不想调整大小,请使用imagecopy,否则如果您想裁剪并调整大小,可以考虑使用imagecopyresampled。

imagecopy(dstImage, $srcImage, 0, 0, $srcX, $srcY, $srcW, $srcH);

Where $srcX is the starting X point in the source image, $srcY the starting Y point, $srcW the width to copy from the starting X point, $srcH the height of the area to be copied.

其中$ srcX是源图像中的起始X点,$ srcY是起始Y点,$ srcW是从起始X点复制的宽度,$ srcH是要复制的区域的高度。

Finally you can either save your image with:

最后,您可以使用以下方式保存图像:

imagejpeg($this->dstImage, $filename, 90);

or you can output it to the browser with:

或者您可以将其输出到浏览器:

imagejpeg($this->dstImage);

If you save the image you've to think in which directory to save it, if you have lots of images (thousands or more), think a way to split them in multiple subdirectory.

如果您保存图像,您需要考虑在哪个目录中保存它,如果您有大量图像(数千或更多),请考虑将它们分割到多个子目录中。

If you save the original image, never save images with extensions not in your list of allowed extension or it will be a huge security hole in which the attacker can send and execute any PHP code to your site.

如果保存原始图像,则永远不要保存扩展名不在允许扩展名列表中的图像,否则将成为攻击者可以向您的站点发送和执行任何PHP代码的巨大安全漏洞。

Based on the concepts described I wrote a small class:

根据描述的概念,我写了一个小班:

class ImageCrop {

    //Image resources
    private $srcImage, $dstImage;

    //original width and height
    private $width, $height;

    /**
    * Read an image from disk.
    * @return true in case of success, false otherwise.
    */
    public function openImage($filename) {
        if (!file_exists($filename)) {
            return false;
        }
        $original = getimagesize($filename);
        switch ($original['mime']) {
        case 'image/jpeg':
            $this->srcImage = imagecreatefromjpeg($filename);
            break;
        case 'image/png':
            $this->srcImage = imagecreatefrompng($filename);
            break;
        case 'image/gif':
            $this->srcImage = imagecreatefromgif($filename);
            break;
        default:
            return false;
        }
        $this->width = $original[0];
        $this->height = $original[1];
        return true;
    }

    /**
    * Crop an image to the new specified dimension trying to get an 
    * internal rectangle of the original image. No crop is done if the 
    * original dimension is already smaller than $newWidth or $newHeight.
    */
    public function crop($newWidth, $newHeight) {
        $this->dstImage = imagecreatetruecolor($newWidth, $newHeight);
        $srcX = $srcY;
        $srcW = $this->width;
        $srcH = $this->height;
        $extraWidth = $this->width - $newWidth;
        if ($extraWidth > 0) {
            $srcX = $extraWidth / 2;        
        }
        $extraHeight = $this->height - $newHeight;
        if ($extraHeight > 0) {
            $srcY = $extraHeight / 2;
        }
        imagecopy($this->dstImage, $this->srcImage, 0, 0, 
            $srcX, $srcY, $srcW, $srcH);
    }

    /**
     * Save the destination image, the crop function should have been 
     * called already.
     */
    public function save($filename) {
        imagejpeg($this->dstImage, $filename, 90);
    }

    /**
    * Output the destination image to the browser.
    */
    public function output() {
        imagejpeg($this->dstImage);
    }

}

Save the class in ImageCrop.php, sample usage:

在ImageCrop.php中保存类,示例用法:

require_once 'ImageCrop.php';

$imageCrop = new ImageCrop();
if ($imageCrop->openImage('big.jpg')) {
    $imageCrop->crop(200, 300); //newWidth, newHeight
    $imageCrop->save('small.jpg');
}

or, to send the output directly to the browser, use $imageCrop->output();.

或者,要将输出直接发送到浏览器,请使用$ imageCrop-> output();.

#1


1  

Say this as max_size.php

把它称为max_size.php

<?php header('Content-type: image/jpeg');
function resampleimage($maxsize, $sourcefile, $imgcomp=0){
$g_imgcomp=100-$imgcomp;
    if(file_exists($sourcefile)){
    $g_is=getimagesize($sourcefile);
        if($g_is[0] <= $maxsize && $g_is[1] <= $maxsize){
            $new_width=$g_is[0];
            $new_height=$g_is[1];
        } else {
            $w_adjust = ($maxsize / $g_is[0]);
            $h_adjust = ($maxsize / $g_is[1]);
      if($w_adjust <= $h_adjust){
          $new_width=($g_is[0]*$w_adjust);
          $new_height=($g_is[1]*$w_adjust);
      } else {
          $new_width=($g_is[0]*$h_adjust);
          $new_height=($g_is[1]*$h_adjust);
      }
    }
    $image_type = strtolower(strrchr($sourcefile, "."));

    switch($image_type) {
      case '.jpg':
         $img_src = imagecreatefromjpeg($sourcefile);
         break;
      case '.jpeg':
         $img_src = imagecreatefromjpeg($sourcefile);
         break;
      case '.png':
         $img_src = imagecreatefrompng($sourcefile);
         break;
      case '.gif':
         $img_src = imagecreatefromgif($sourcefile);
         break;
      default:
         echo("Error Invalid Image Type");
         die;
         break;
   }
  $img_dst=imagecreatetruecolor($new_width,$new_height);
  imagecopyresampled($img_dst, $img_src, 0, 0, 0, 0, $new_width, $new_height, $g_is[0], $g_is[1]);
  imagejpeg($img_dst);
  imagedestroy($img_dst);
  return true;
  } else {
  return false;
  }
}
resampleimage($_GET['maxsize'], $_GET['source']);
?>

In the page where you have image

在您有图像的页面中

<img id="img" src="max_size.php?maxsize=152&source=[some image path]" />

#2


2  

Automatic cropping would be difficult without knowing where is the subject. Maybe you can try to get an inner centered rectangle, like in the picture:

如果不知道主题在哪里,自动裁剪将很困难。也许你可以尝试获得一个内部居中的矩形,如图所示:

自动在浏览器中裁剪图像

The first thing to do is find the original image dimensions and file type. You should not trust the image extension and instead use getimagesize for that. Despite the name getimagesize not only returns the size but also the file type.

首先要做的是找到原始图像尺寸和文件类型。你不应该相信图像扩展,而是使用getimagesize。尽管名称getimagesize不仅返回大小,还返回文件类型。

//width is at index 0, height at index 1, mime type at ['mime'] key
$original = getimagesize($filename); 

Then you should build an internal PHP data structure to hold the source image in memory, so you can manipulate it, using imagecreatefromjpeg or imagecreatefrompng or imagecreatefromgif, depending on the image type. For instance:

然后你应该构建一个内部PHP数据结构来将源图像保存在内存中,这样你就可以使用imagecreatefromjpeg或imagecreatefrompng或imagecreatefromgif来操作它,具体取决于图像类型。例如:

$srcImage = imagecreatefromjpeg($filename);

Next, you should allocate another data structure to hold the destination image. In this case we don't have an image to start with, so I allocate an empty image.

接下来,您应该分配另一个数据结构来保存目标图像。在这种情况下,我们没有图像开头,所以我分配一个空图像。

$dstImage = imagecreatetruecolor($newWidth, $newHeight);

Next, you should copy a portion of the original image to the destination image. If you don't want to resize, use imagecopy, otherwise if you want to crop and resize you can consider imagecopyresampled.

接下来,您应该将原始图像的一部分复制到目标图像。如果您不想调整大小,请使用imagecopy,否则如果您想裁剪并调整大小,可以考虑使用imagecopyresampled。

imagecopy(dstImage, $srcImage, 0, 0, $srcX, $srcY, $srcW, $srcH);

Where $srcX is the starting X point in the source image, $srcY the starting Y point, $srcW the width to copy from the starting X point, $srcH the height of the area to be copied.

其中$ srcX是源图像中的起始X点,$ srcY是起始Y点,$ srcW是从起始X点复制的宽度,$ srcH是要复制的区域的高度。

Finally you can either save your image with:

最后,您可以使用以下方式保存图像:

imagejpeg($this->dstImage, $filename, 90);

or you can output it to the browser with:

或者您可以将其输出到浏览器:

imagejpeg($this->dstImage);

If you save the image you've to think in which directory to save it, if you have lots of images (thousands or more), think a way to split them in multiple subdirectory.

如果您保存图像,您需要考虑在哪个目录中保存它,如果您有大量图像(数千或更多),请考虑将它们分割到多个子目录中。

If you save the original image, never save images with extensions not in your list of allowed extension or it will be a huge security hole in which the attacker can send and execute any PHP code to your site.

如果保存原始图像,则永远不要保存扩展名不在允许扩展名列表中的图像,否则将成为攻击者可以向您的站点发送和执行任何PHP代码的巨大安全漏洞。

Based on the concepts described I wrote a small class:

根据描述的概念,我写了一个小班:

class ImageCrop {

    //Image resources
    private $srcImage, $dstImage;

    //original width and height
    private $width, $height;

    /**
    * Read an image from disk.
    * @return true in case of success, false otherwise.
    */
    public function openImage($filename) {
        if (!file_exists($filename)) {
            return false;
        }
        $original = getimagesize($filename);
        switch ($original['mime']) {
        case 'image/jpeg':
            $this->srcImage = imagecreatefromjpeg($filename);
            break;
        case 'image/png':
            $this->srcImage = imagecreatefrompng($filename);
            break;
        case 'image/gif':
            $this->srcImage = imagecreatefromgif($filename);
            break;
        default:
            return false;
        }
        $this->width = $original[0];
        $this->height = $original[1];
        return true;
    }

    /**
    * Crop an image to the new specified dimension trying to get an 
    * internal rectangle of the original image. No crop is done if the 
    * original dimension is already smaller than $newWidth or $newHeight.
    */
    public function crop($newWidth, $newHeight) {
        $this->dstImage = imagecreatetruecolor($newWidth, $newHeight);
        $srcX = $srcY;
        $srcW = $this->width;
        $srcH = $this->height;
        $extraWidth = $this->width - $newWidth;
        if ($extraWidth > 0) {
            $srcX = $extraWidth / 2;        
        }
        $extraHeight = $this->height - $newHeight;
        if ($extraHeight > 0) {
            $srcY = $extraHeight / 2;
        }
        imagecopy($this->dstImage, $this->srcImage, 0, 0, 
            $srcX, $srcY, $srcW, $srcH);
    }

    /**
     * Save the destination image, the crop function should have been 
     * called already.
     */
    public function save($filename) {
        imagejpeg($this->dstImage, $filename, 90);
    }

    /**
    * Output the destination image to the browser.
    */
    public function output() {
        imagejpeg($this->dstImage);
    }

}

Save the class in ImageCrop.php, sample usage:

在ImageCrop.php中保存类,示例用法:

require_once 'ImageCrop.php';

$imageCrop = new ImageCrop();
if ($imageCrop->openImage('big.jpg')) {
    $imageCrop->crop(200, 300); //newWidth, newHeight
    $imageCrop->save('small.jpg');
}

or, to send the output directly to the browser, use $imageCrop->output();.

或者,要将输出直接发送到浏览器,请使用$ imageCrop-> output();.