0

代码

$files = scandir("images");
$exclude = array(".", "..");

$images = array_diff($files, $exclude);

foreach($images as $image) {

    $original_image  = imagecreatefromjpeg("images/{$image}");
    $original_width  = imagesx($original_image);
    $original_height = imagesy($original_image);

    $new_width  = 180;
    $new_height = floor($original_height * ($new_width/$original_width));
    $new_image  = imagecreatetruecolor($new_width, $new_height);

    imagecopyresampled($new_image, $original_image, 0, 0, 0, 0, $new_width, $new_height, $original_width, $original_height);

    header("Content-Type: image/jpeg");

    imagejpeg($new_image);
}

问题

代码的调整大小部分工作得很好,但它只输出第一个调整大小的图像。我怎样才能让它转储所有调整大小的图像?

4

2 回答 2

2

你不能这样做。imagejpeg“打印”图像的字节(这就是为什么结合正确的标题,您会在浏览器中看到该图片)。但是,打印多个图像(加上尝试更改标题)将不起作用,因为您正在“修改”第一个图像的字节,而不是将新图像附加到输出中。如果您想使用这样的解决方案,您可以:

  1. 将每个图像保存在服务器中,然后以另一种方式访问​​这些图像(通过打印<img>指向图片的标签或抛出某种列出图像的结构)。

  2. 如果您不想保存它们,您始终可以使用 base64 对字节进行编码,然后将其用作<img src>

    ob_start ();
    imagejpeg ($new_image);
    $image_data = ob_get_contents ();
    ob_end_clean ();
    $image_data_base64 = base64_encode ($image_data);
    echo '<img src="data:image/jpg;base64,'.$image_data_base64.'" />';
    

你应该每次都这样做。

并且非常重要:始终imagedestroy($new_image)在 php 中输出(或完成您的工作)图像对象后使用:它将释放资源,因此您不会那么容易收到“内存耗尽”错误。

于 2013-01-30T15:14:34.477 回答
1

该行:

header("Content-Type: image/jpeg");

让您的浏览器了解您的内容是图像

这就是如果您在一个文件夹中选择 2 个图像,右键单击并打开它们。您的图像不会像只有一张一样显示在一起。

完成工作的一种方法是创建一个执行 2 件事的页面:

  • 如果有参数则显示图像
  • <img>如果没有参数,则将所有图像显示为标签

这是一个例子。

// The argument is set: we display one image as png
if (array_key_exists('img', $_GET)) {

    $image = $_GET['img'];

    // security: prevents access to unauthorized directories (by giving "../../file.jpg" as file)
    $goodPath = realpath('images');
    $wantedImage = realpath("images/{$image}");
    if (strncmp($wantedImage, $goodPath, strlen($goodPath)) != 0) {
        die();
    }

    // if user wants an image that does not exists, we prevent GD errors
    if (!is_file($wantedImage))
    {
        die();
    }

    // and your code here, to display only ONE image

    $original_image  = imagecreatefromjpeg("images/{$image}");
    $original_width  = imagesx($original_image);
    $original_height = imagesy($original_image);

    $new_width  = 180;
    $new_height = floor($original_height * ($new_width/$original_width));
    $new_image  = imagecreatetruecolor($new_width, $new_height);

    imagecopyresampled($new_image, $original_image, 0, 0, 0, 0, $new_width, $new_height, $original_width, $original_height);

    header("Content-Type: image/jpeg");
    imagejpeg($new_image);
    die();

// No argument: we display all images as image tags
} else {

    // security: prevents from xss exploits 
    $self = htmlentities($_SERVER['PHP_SELF']);

    // glob will get all files that matches your pattern
    $files = glob("images/*.[jJ][pP][gG]");

    // display image tags
    foreach ($files as $image) {
       $image = htmlentities($image);
       echo "<img src='{$self}?img={$image}' />";
    }

    die();

}
于 2013-01-30T20:22:22.040 回答