如何使用 GD 调整上传的图像大小并将其转换为 PNG?

发布于 2024-07-05 00:24:23 字数 303 浏览 7 评论 0原文

我希望允许用户上传各种格式的头像类型图像(至少是 GIF、JPEG 和 PNG),但将它们全部保存为 PNG 数据库 BLOB 。 如果图像尺寸过大,按像素计算,我想在数据库插入之前调整它们的大小。

使用 GD 进行大小调整和 PNG 转换的最佳方法是什么?

编辑:遗憾的是,只有 GD 在我需要使用的服务器上可用,没有

I want to allow users to upload avatar-type images in a variety of formats (GIF, JPEG, and PNG at least), but to save them all as PNG database BLOBs. If the images are oversized, pixelwise, I want to resize them before DB-insertion.

What is the best way to use GD to do the resizing and PNG conversion?

Edit: Sadly, only GD is available on the server I need to use, no ImageMagick.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

他是夢罘是命 2024-07-12 00:24:23

您确定服务器上没有 ImageMagick 吗?

我猜你使用 PHP(问题被标记为 PHP)。 根据 phpinfo(),我使用的托管公司没有打开 ImageMagick 扩展。

但当我询问他们时,他们说这里是 PHP 代码中可用的 ImageMagick 程序列表。 很简单——PHP 中没有 IM 接口,但我可以直接从 PHP 调用 IM 程序。

我希望你也有同样的选择。

强烈同意——将图像存储在数据库中并不是一个好主意。

Are you sure you have no ImageMagick on server?

I guest you use PHP (question is tagged with PHP). Hosting company which I use has no ImageMagick extension turned on according to phpinfo().

But when I asked them about they said here is the list of ImageMagick programs available from PHP code. So simply -- there are no IM interface in PHP, but I can call IM programs directly from PHP.

I hope you have the same option.

And I strongly agree -- storing images in database is not good idea.

笔芯 2024-07-12 00:24:23

phpThumb 是一个可能值得研究的高级抽象。

phpThumb is a high-level abstraction that may be worth looking at.

独自←快乐 2024-07-12 00:24:23

我认为此页面是良好的起点。 它使用 imagecreatefrom(jpeg/gif/png) 调整图像大小并转换图像,然后输出到浏览器。 您可以输出到数据库中的 BLOB,而不是输出到浏览器,而无需进行许多分钟的代码重写。

I think this page is a good starting point. It uses imagecreatefrom(jpeg/gif/png) and resize and converts the image and then outputs to the browser. Instead of outputting the browser you could output to a BLOB in a DB without many minuttes of code-rewrite.

不羁少年 2024-07-12 00:24:23

GD是绝对必要的吗? ImageMagick 更快,生成更好的图像,更可配置,并且最终(IMO)更容易编码。

Is GD absolutely required? ImageMagick is faster, generates better images, is more configurable, and finally is (IMO) much easier to code for.

り繁华旳梦境 2024-07-12 00:24:23

这篇文章看起来很适合你想要的。 您需要将保存 imagejpeg() 函数更改为 imagepng() 并将文件保存到字符串而不是输出到页面,但除此之外,它应该很容易复制/粘贴到现有代码中。

This article seems like it would fit what you want. You'll need to change the saving imagejpeg() function to imagepng() and have it save the file to a string rather than output it to the page, but other than that it should be easy copy/paste into your existing code.

天邊彩虹 2024-07-12 00:24:23

也许是这样的:


<?php
   //Input file
   $file = "myImage.png";
   $img = ImageCreateFromPNG($file);

   //Dimensions
   $width = imagesx($img);
   $height = imagesy($img);
   $max_width = 300;
   $max_height = 300;
   $percentage = 1;

   //Image scaling calculations
   if ( $width > $max_width ) { 
      $percentage = ($height / ($width / $max_width)) > $max_height ?
           $height / $max_height :
           $width / $max_width;
   }
   elseif ( $height > $max_height) {
      $percentage = ($width / ($height / $max_height)) > $max_width ? 
           $width / $max_width :
           $height / $max_height;
   }
   $new_width = $width / $percentage;
   $new_height = $height / $percentage;

   //scaled image
   $out = imagecreatetruecolor($new_width, $new_height);
   imagecopyresampled($out, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

   //output image
   imagepng($out);
?>

我还没有测试代码,因此可能存在一些语法错误,但是它应该为您提供一个关于如何完成它的公平演示。 另外,我假设了一个 PNG 文件。 您可能需要某种 switch 语句来确定文件类型。

Something like this, perhaps:


<?php
   //Input file
   $file = "myImage.png";
   $img = ImageCreateFromPNG($file);

   //Dimensions
   $width = imagesx($img);
   $height = imagesy($img);
   $max_width = 300;
   $max_height = 300;
   $percentage = 1;

   //Image scaling calculations
   if ( $width > $max_width ) { 
      $percentage = ($height / ($width / $max_width)) > $max_height ?
           $height / $max_height :
           $width / $max_width;
   }
   elseif ( $height > $max_height) {
      $percentage = ($width / ($height / $max_height)) > $max_width ? 
           $width / $max_width :
           $height / $max_height;
   }
   $new_width = $width / $percentage;
   $new_height = $height / $percentage;

   //scaled image
   $out = imagecreatetruecolor($new_width, $new_height);
   imagecopyresampled($out, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

   //output image
   imagepng($out);
?>

I haven't tested the code so there might be some syntax errors, however it should give you a fair presentation on how it could be done. Also, I assumed a PNG file. You might want to have some kind of switch statement to determine the file type.

眼眸里的快感 2024-07-12 00:24:23

如果您想使用 gdlib,请使用 gdlib 2 或更高版本。 它有一个名为 imagecopyresampled() 的函数,该函数将在调整大小时插入像素并且看起来更好。

另外,我总是在网上听说将图像存储在数据库中是一种不好的形式:

  • 访问速度比磁盘慢
  • 您的服务器将需要运行脚本来访问图像
    简单地提供一个文件
  • 您的脚本现在负责 Web 服务器使用的许多内容
    处理:

    • 设置正确的 Content-Type 标头
    • 设置正确的缓存/超时/E-tag 标头,以便客户端可以正确缓存图像。 如果没有正确执行此操作,图像服务脚本将在每次请求时都会被命中,从而进一步增加服务器的负载。

我能看到的唯一优点是您不需要保持数据库和图像文件同步。 但我仍然建议反对。

If you want to use gdlib, use gdlib 2 or higher. It has a function called imagecopyresampled(), which will interpolate pixels while resizing and look much better.

Also, I've always heard noted around the net that storing images in the database is bad form:

  • It's slower to access than the disk
  • Your server will need to run a script to get to the image instead
    of simply serving a file
  • Your script now is responsible for a lot of stuff the web server used
    to handle:

    • Setting the proper Content-Type header
    • Setting the proper caching/timeout/E-tag headers, so clients can properly cache the image. If do not do this properly, the image serving script will be hit on every request, increasing the load on the server even more.

The only advantage I can see is that you don't need to keep your database and image files synchronized. I would still recommend against it though.

黯然#的苍凉 2024-07-12 00:24:23

您的流程步骤应如下所示:

  1. 验证 文件类型
  2. 如果图像是受支持的文件类型,则使用 imagecreatefrom*
  3. 使用 imagecopyresizeimagecopyresampled
  4. 使用 imagepng( $handle, 'filename.png', $quality, $filters)

ImageMagick 更快,生成更好的图像,更可配置,并且最终(IMO)更容易编码。

@ceejayoz 等待新的 GD - 它是像 MySQLi 一样的 OOP,而且实际上还不错:)

Your process steps should look like this:

  1. Verify the filetype
  2. Load the image if it is a supported filetype into GD using imagecreatefrom*
  3. Resizing using imagecopyresize or imagecopyresampled
  4. Save the image using imagepng($handle, 'filename.png', $quality, $filters)

ImageMagick is faster, generates better images, is more configurable, and finally is (IMO) much easier to code for.

@ceejayoz Just wait for the new GD - it's OOP like MySQLi and it's actually not bad :)

尸血腥色 2024-07-12 00:24:23
<?php                                              
/*
Resizes an image and converts it to PNG returning the PNG data as a string
*/
function imageToPng($srcFile, $maxSize = 100) {  
    list($width_orig, $height_orig, $type) = getimagesize($srcFile);        

    // Get the aspect ratio
    $ratio_orig = $width_orig / $height_orig;

    $width  = $maxSize; 
    $height = $maxSize;

    // resize to height (orig is portrait) 
    if ($ratio_orig < 1) {
        $width = $height * $ratio_orig;
    } 
    // resize to width (orig is landscape)
    else {
        $height = $width / $ratio_orig;
    }

    // Temporarily increase the memory limit to allow for larger images
    ini_set('memory_limit', '32M'); 

    switch ($type) 
    {
        case IMAGETYPE_GIF: 
            $image = imagecreatefromgif($srcFile); 
            break;   
        case IMAGETYPE_JPEG:  
            $image = imagecreatefromjpeg($srcFile); 
            break;   
        case IMAGETYPE_PNG:  
            $image = imagecreatefrompng($srcFile);
            break; 
        default:
            throw new Exception('Unrecognized image type ' . $type);
    }

    // create a new blank image
    $newImage = imagecreatetruecolor($width, $height);

    // Copy the old image to the new image
    imagecopyresampled($newImage, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);

    // Output to a temp file
    $destFile = tempnam();
    imagepng($newImage, $destFile);  

    // Free memory                           
    imagedestroy($newImage);

    if ( is_file($destFile) ) {
        $f = fopen($destFile, 'rb');   
        $data = fread($f);       
        fclose($f);

        // Remove the tempfile
        unlink($destFile);    
        return $data;
    }

    throw new Exception('Image conversion failed.');
}
<?php                                              
/*
Resizes an image and converts it to PNG returning the PNG data as a string
*/
function imageToPng($srcFile, $maxSize = 100) {  
    list($width_orig, $height_orig, $type) = getimagesize($srcFile);        

    // Get the aspect ratio
    $ratio_orig = $width_orig / $height_orig;

    $width  = $maxSize; 
    $height = $maxSize;

    // resize to height (orig is portrait) 
    if ($ratio_orig < 1) {
        $width = $height * $ratio_orig;
    } 
    // resize to width (orig is landscape)
    else {
        $height = $width / $ratio_orig;
    }

    // Temporarily increase the memory limit to allow for larger images
    ini_set('memory_limit', '32M'); 

    switch ($type) 
    {
        case IMAGETYPE_GIF: 
            $image = imagecreatefromgif($srcFile); 
            break;   
        case IMAGETYPE_JPEG:  
            $image = imagecreatefromjpeg($srcFile); 
            break;   
        case IMAGETYPE_PNG:  
            $image = imagecreatefrompng($srcFile);
            break; 
        default:
            throw new Exception('Unrecognized image type ' . $type);
    }

    // create a new blank image
    $newImage = imagecreatetruecolor($width, $height);

    // Copy the old image to the new image
    imagecopyresampled($newImage, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);

    // Output to a temp file
    $destFile = tempnam();
    imagepng($newImage, $destFile);  

    // Free memory                           
    imagedestroy($newImage);

    if ( is_file($destFile) ) {
        $f = fopen($destFile, 'rb');   
        $data = fread($f);       
        fclose($f);

        // Remove the tempfile
        unlink($destFile);    
        return $data;
    }

    throw new Exception('Image conversion failed.');
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文