无法上传质量为 100% 的图片

Can't upload image with 100% quality

我正在尝试通过 PHP 上传图片,但无法上传 100% 质量的图片。

我实际使用的代码

class imaging
{

    // Variables
    private $img_input;
    private $img_output;
    private $img_src;
    private $format;
    private $quality = 100;
    private $x_input;
    private $y_input;
    private $x_output;
    private $y_output;
    private $resize;

    // Set image
    public function upload($orig, $name, $path)
    {
        move_uploaded_file($orig, __DIR__ . "/../uploads/" . $path . 'orig_' . $name);
    }

    public function set_img($img)
    {
        //$img = __DIR__ . '/../uploads/' . $img;

        $img = '../uploads/' . $img;

        // Find format
        $ext = strtoupper(pathinfo($img, PATHINFO_EXTENSION));

        // JPEG image
        if(is_file($img) && ($ext == "JPG" OR $ext == "JPEG"))
        {
            $this->format = $ext;
            $this->img_input = ImageCreateFromJPEG($img);
            $this->img_src = $img;

        }

        // PNG image
        elseif(is_file($img) && $ext == "PNG")
        {

            $this->format = $ext;
            $this->img_input = ImageCreateFromPNG($img);
            $this->img_src = $img;

        }

        // GIF image
        elseif(is_file($img) && $ext == "GIF")
        {

            $this->format = $ext;
            $this->img_input = ImageCreateFromGIF($img);
            $this->img_src = $img;

        }

        // Get dimensions
        $this->x_input = imagesx($this->img_input);
        $this->y_input = imagesy($this->img_input);
    }

    // Set maximum image size (pixels)
    public function set_size($size = 100)
    {
        // Wide
        if($this->x_input >= $this->y_input && $this->x_input > $size)
        {
            $this->x_output = $size;
            $this->y_output = ($this->x_output / $this->x_input) * $this->y_input;

            $this->resize = TRUE;
        }

        // Tall
        elseif($this->y_input > $this->x_input && $this->y_input > $size)
        {
            $this->y_output = $size;
            $this->x_output = ($this->y_output / $this->y_input) * $this->x_input;

            $this->resize = TRUE;
        }

        // Don't resize
        else { $this->resize = FALSE; }

    }

    // Set image quality (JPEG only)
    public function set_quality($quality)
    {

        if(is_int($quality))
        {

            $this->quality = $quality;

        }

    }

    // Save image
    public function save_img($path)
    {

        // Resize
        if($this->resize)
        {

            $this->img_output = ImageCreateTrueColor($this->x_output, $this->y_output);
            ImageCopyResampled($this->img_output, $this->img_input, 0, 0, 0, 0, $this->x_output, $this->y_output, $this->x_input, $this->y_input);

        }

        // Save JPEG
        if($this->format == "JPG" OR $this->format == "JPEG")
        {

            if($this->resize) { imageJPEG($this->img_output, __DIR__ . "/../uploads/" . $path, $this->quality); }
            else { copy($this->img_src, __DIR__ . "/../uploads/" . $path); }

        }

        // Save PNG
        elseif($this->format == "PNG")
        {

            if($this->resize) { imagePNG($this->img_output, __DIR__ . "/../uploads/" . $path, 9); }
            else { copy($this->img_src, __DIR__ . "/../uploads/" . $path); }

        }

        // Save GIF
        elseif($this->format == "GIF")
        {

            if($this->resize) { imageGIF($this->img_output, __DIR__ . "/../uploads/" . $path); }
            else { copy($this->img_src, __DIR__ . "/../uploads/" . $path); }

        }

    }

    // Get width
    public function get_width()
    {

        return $this->x_input;

    }

    // Get height
    public function get_height()
    {

        return $this->y_input;

    }

    // Clear image cache
    public function clear_cache()
    {

        @ImageDestroy($this->img_input);
        @ImageDestroy($this->img_output);

    }

}

并调用上传

$img = new imaging;
$img->upload($src['tmp_name'], $name, $dir);
$img->set_img($dir . 'orig_' . $name); // upload original file
$img->set_quality(100);

// Small thumbnail
$img->set_size(700);                   // upload thumbnail
$img->save_img($dir . $name);

// Finalize
$img->clear_cache();

效果不太好,不如设置quality=100。原始文件(宽度 cca 1100px)已正确上传(服务器上未调整大小),当我在 Photoshop 中打开它时,将其调整为 700px 宽度并与 PHP 中调整大小的 700px 拇指进行比较,质量差异很大。

查看两张图片,原始图片在 Photoshop 中调整大小(顶部)并通过 PHP 调整图片大小(底部)- 文本、图像等模糊,颜色不亮。

原始大小




在 Photoshop 中放大 200%


有什么想法吗?感谢您的回复:-)

我要在这里回答,因为我没有足够的声誉来发表评论。

要调整图像大小,我认为最好使用命令imagescale。最好使用 ImageCreateTrueColor + ImageCopyResampled.

所以我会这样做

        // Resize
        if($this->resize)
        {
            $this->img_output = imagescale($this->img_input, $this->x_output, $this->y_output);

        }

但是您还可以更改其他一些内容:

  • 我创建了方法 create_thumbnail(),您将向它传递图像路径、保存新图像的路径以及可选的大小(默认 100)。
  • 要有宽度和高度,您不需要创建图像。你可以用方法getimagesize来做,这样你会节省很多资源。
  • 当您调用调整大小的方法时,它会根据需要调整图像的大小。
  • 并且当你要保存图片时,你可以知道图片是否已经调整过大小,所以你是否复制它。

此外,我尝试不重复任何代码并优化资源。

编辑:您也可以清除缓存并结束进程。

class imaging
{

    // Variables
    private $img_input;
    private $img_output;
    private $img_src;
    private $format;
    private $quality = 100;
    private $x_input;
    private $y_input;
    private $x_output;
    private $y_output;
    private $resize;

    // Set image
    public function upload($orig, $name, $path)
    {
        move_uploaded_file($orig, __DIR__ . "/../uploads/" . $path . 'orig_' . $name);
    }

        // Set image quality (JPEG only)
    public function set_quality($quality)
    {

        if(is_int($quality))
        {

            $this->quality = $quality;

        }

    }

    // Set maximum image size (pixels)
    private function resize($size = 100)
    {   
        $resize = FALSE; 
        // Wide
        if($this->x_input >= $this->y_input && $this->x_input > $size)
        {
            $this->x_output = $size;
            $this->y_output = ($this->x_output / $this->x_input) * $this->y_input;

            $resize = TRUE;
        }

        // Tall
        elseif($this->y_input > $this->x_input && $this->y_input > $size)
        {
            $this->y_output = $size;
            $this->x_output = ($this->y_output / $this->y_input) * $this->x_input;

            $resize = TRUE;
        }

        if($resize){

            switch ($this->format) {
                case 'JPEG':
                case 'JPG':
                    $this->img_input = ImageCreateFromJPEG($img);
                    break;
                case 'PNG':
                    $this->img_input = ImageCreateFromPNG($img);
                    break;
                case 'GIF':
                    $this->img_input = ImageCreateFromGIF($img);
                    break;
                
                default:
                    throw new Exception("This extension " . $ext . " it's not compatible.");
                    
                    break;
            }

        }

    }

    // Save image
    public function save_img($path)
    {
        // We have resized the image
        if($this->img_input){
            switch ($this->format) {
                case 'JPEG':
                case 'JPG':
                    imageJPEG($this->img_output, __DIR__ . "/../uploads/" . $path, $this->quality);
                    break;
                case 'PNG':
                    imagePNG( $this->img_output, __DIR__ . "/../uploads/" . $path, 9);
                    break;
                case 'GIF':
                    imageGIF( $this->img_output, __DIR__ . "/../uploads/" . $path);
                    break;
                
                default:
                    throw new Exception("This extension " . $ext . " it's not compatible.");
                    
                    break;
            }
        }else{
            copy($this->img_src, __DIR__ . "/../uploads/" . $path);
        }

    }

    public function create_thumbnail($imgSrc, $savePath, $size = 100)
    {
        $this->img_src = '../uploads/' . $img;

        if(file_exists($this->img_src)){
            list($this->x_input, $this->y_input) = getimagesize($imageSrc);
            $this->format = strtoupper(pathinfo($img, PATHINFO_EXTENSION));
            $this->resize($size);
            $this->save_img($savePath);
            $this->clear_cache();
        }else{
            throw new Exception("Image not found in " . $imdSrc);
        }

    }

    // Get width
    public function get_width()
    {

        return $this->x_input;

    }

    // Get height
    public function get_height()
    {

        return $this->y_input;

    }

    // Clear image cache
    public function clear_cache()
    {

        @ImageDestroy($this->img_input);
        @ImageDestroy($this->img_output);

    }

}

你可以试试这个包http://image.intervention.io/getting_started/introduction . http://image.intervention.io/getting_started/installation,这里有所有的配置说明。 它应该可以正常工作并且很容易使用 composer 进行设置。

我建议您使用 Intervention Image Library 进行图像处理和操作。我过去遇到过此类问题,切换到其他库后问题就解决了。

其次,这个库的使用非常简单,网站上已经有。

我会推荐

将您的图像转换为 base64,然后更新 base64 字符串,然后在服务器端再次将该 base64 字符串转换为图像。你会找到转换的方法

图像转 base64:

base64 转图片: