【问题标题】:Unable to create thumb, image is black无法创建拇指,图像为黑色
【发布时间】:2014-11-06 13:59:02
【问题描述】:

我正在从单个输入上传多个图像并创建拇指表单所有上传的图像但是当我运行代码时我只得到黑色图像但原始图像与上传的图像相同

    <?php

$newname = md5(rand() * time());
$file1 = isset($_FILES['files']['name'][0]) ? $_FILES['files']['name'][0] : null;
$file2 = isset($_FILES['files']['name'][1]) ? $_FILES['files']['name'][1] : null;
$file3 = isset($_FILES['files']['name'][2]) ? $_FILES['files']['name'][2] : null;
$file4 = isset($_FILES['files']['name'][3]) ? $_FILES['files']['name'][3] : null;
$file5 = isset($_FILES['files']['name'][4]) ? $_FILES['files']['name'][4] : null;
if (isset($_FILES['files'])) {
    $errors = array();
    foreach ($_FILES['files']['tmp_name'] as $key => $tmp_name) {
        $file_name = $key . $_FILES['files']['name'][$key];
        $file_size = $_FILES['files']['size'][$key];
        $file_tmp = $_FILES['files']['tmp_name'][$key];
        $file_type = $_FILES['files']['type'][$key];
        if ($file_size > 2097152000) {
            $errors[] = 'File size must be less than 2 MB';
        }
        $desired_dir = "user_data/";
        if (empty($errors) == true) {
            if (is_dir($desired_dir) == false) {
                mkdir("$desired_dir", 0700);        // Create directory if it does not exist
            }
            if (is_dir("$desired_dir/" . $file_name) == false) {
                move_uploaded_file($file_tmp, "$desired_dir/" . $newname . $file_name);
            } else {                                  // rename the file if another one exist
                $new_dir = "$desired_dir/" . $newname . $file_name;
                rename($file_tmp, $new_dir);
            }
        } else {
            print_r($errors);
        }
    }
    if (empty($error)) {
        echo "FILE : $file1<br>";
        echo "FILE : $file2<br>";
        echo "FILE : $file3<br>";
        echo "FILE : $file4<br>";
        echo "FILE : $file5<br>";
    }
}
$orig_directory = "$desired_dir";    //Full image folder
$thumb_directory =  "thumb/";    //Thumbnail folder

/* Opening the thumbnail directory and looping through all the thumbs: */
$dir_handle = @opendir($orig_directory); //Open Full image dirrectory
if ($dir_handle > 1){ //Check to make sure the folder opened

$allowed_types=array('jpg','jpeg','gif','png');
$file_type=array();
$ext='';
$title='';
$i=0;

while ($file_name = @readdir($dir_handle)) {
    /* Skipping the system files: */
    if($file_name=='.' || $file_name == '..') continue;

    $file_type = explode('.',$file_name);    //This gets the file name of the images
    $ext = strtolower(array_pop($file_type));

    /* Using the file name (withouth the extension) as a image title: */
    $title = implode('.',$file_type);
    $title = htmlspecialchars($title);

    /* If the file extension is allowed: */
    if(in_array($ext,$allowed_types)) {

        /* If you would like to inpute images into a database, do your mysql query here */

        /* The code past here is the code at the start of the tutorial */
        /* Outputting each image: */

        $nw = 100;
        $nh = 100;
        $source = "$desired_dir{$file_name}";
        $stype = explode(".", $source);
        $stype = $stype[count($stype)-1];
        $dest = "thumb/{$file_name}";

        $size = getimagesize($source);
        $w = $size[0];
        $h = $size[1];

        switch($stype) {
            case 'gif':
                $simg = imagecreatefromgif($source);
                break;
            case 'jpg': 
                $simg = imagecreatefromjpeg($source);
                break;
            case 'png':
                $simg = imagecreatefrompng($source);
                break;
        }

        $dimg = imagecreatetruecolor($nw, $nh);
        $wm = $w/$nw;
        $hm = $h/$nw;
        $h_height = $nh/2;
        $w_height = $nw/2;

        if($w> $h) {
            $adjusted_width = $w / $hm;
            $half_width = $adjusted_width / 2;
            $int_width = $w / $hm;
            imagecopyresampled($dimg,$simg,-$int_width,0,0,0,$adjusted_width,$nh,$w,$h);
        } else {
            imagecopyresampled($dimg,$simg,0,0,0,0,$nw,$nh,$w,$h);
        }
            imagejpeg($dimg,$dest,100);
        }
}

/* Closing the directory */
@closedir($dir_handle);

}
?>

当我运行代码时,这是如何输出文件的,不知道发生了什么,有人可以帮我找到错误吗 为所有类型的图像格式创建黑色拇指

当我从上面的代码中删除以下代码时,它的工作原理是这段代码的作用

if($w> $h) {
        $adjusted_width = $w / $hm;
        $half_width = $adjusted_width / 2;
        $int_width = $w / $hm;
        imagecopyresampled($dimg,$simg,-$int_width,0,0,0,0,$adjusted_width,$nw,$nh,$w,$h);
    } else 

【问题讨论】:

  • 您的文件有哪些文件扩展名?
  • $source="$desired_dir{$file_name}" ???为什么不 $source = $desired_dir."/".$file_name;
  • @RaphaelMüller 我有 JPG、PNG、GIF 所有图像格式
  • 我在您的交换机中看到了。但是你只检查 jpg 如果扩展名是 jpeg 你会得到一个黑色的拇指
  • 抱歉转储问题,但是您在发送原始文件时是否发送大写字母?比如JPG、PNG等...

标签: php image thumbnails


【解决方案1】:

问题

问题出在下面一行:

imagecopyresampled($dimg, $simg, -$int_width, 0, 0, 0, $adjusted_width, $nh, $w, $h);

为什么使用负值作为目的地的 x?您的源图像实际上放在目标图像的左侧,因此您的目标图像显示为空。

解决方案

我邀请您使用以下功能来调整图像大小:

function resizePreservingAspectRatio($img, $targetWidth, $targetHeight)
{
   $srcWidth = imagesx($img);
   $srcHeight = imagesy($img);

   // Determine new width / height preserving aspect ratio
   $srcRatio = $srcWidth / $srcHeight;
   $targetRatio = $targetWidth / $targetHeight;
   if (($srcWidth <= $targetWidth) && ($srcHeight <= $targetHeight))
   {
      $imgTargetWidth = $srcWidth;
      $imgTargetHeight = $srcHeight;
   }
   else if ($targetRatio > $srcRatio)
   {
      $imgTargetWidth = (int) ($targetHeight * $srcRatio);
      $imgTargetHeight = $targetHeight;
   }
   else
   {
      $imgTargetWidth = $targetWidth;
      $imgTargetHeight = (int) ($targetWidth / $srcRatio);
   }

   // Creating new image with desired size
   $targetImg = imagecreatetruecolor($targetWidth, $targetHeight);

   // Add transparency if your reduced image does not fit with the new size
   $targetTransparent = imagecolorallocate($targetImg, 255, 0, 255);
   imagefill($targetImg, 0, 0, $targetTransparent);
   imagecolortransparent($targetImg, $targetTransparent);

   // Copies image, centered to the new one (if it does not fit to it)
   imagecopyresampled(
      $targetImg, $img, ($targetWidth - $imgTargetWidth) / 2, // centered
      ($targetHeight - $imgTargetHeight) / 2, // centered
      0, 0, $imgTargetWidth, $imgTargetHeight, $srcWidth, $srcHeight
   );

   return $targetImg;
}

实施

<?php
$newname = md5(rand() * time());
$file1 = isset($_FILES['files']['name'][0]) ? $_FILES['files']['name'][0] : null;
$file2 = isset($_FILES['files']['name'][1]) ? $_FILES['files']['name'][1] : null;
$file3 = isset($_FILES['files']['name'][2]) ? $_FILES['files']['name'][2] : null;
$file4 = isset($_FILES['files']['name'][3]) ? $_FILES['files']['name'][3] : null;
$file5 = isset($_FILES['files']['name'][4]) ? $_FILES['files']['name'][4] : null;
if (isset($_FILES['files']))
{
   $errors = array ();
   foreach ($_FILES['files']['tmp_name'] as $key => $tmp_name)
   {
      $file_name = $key . $_FILES['files']['name'][$key];
      $file_size = $_FILES['files']['size'][$key];
      $file_tmp = $_FILES['files']['tmp_name'][$key];
      $file_type = $_FILES['files']['type'][$key];
      if ($file_size > 2097152000)
      {
         $errors[] = 'File size must be less than 2 MB';
      }
      $desired_dir = "user_data/";
      if (empty($errors) == true)
      {
         if (is_dir($desired_dir) == false)
         {
            mkdir("$desired_dir", 0700);        // Create directory if it does not exist
         }
         if (is_dir("$desired_dir/" . $file_name) == false)
         {
            move_uploaded_file($file_tmp, "$desired_dir/" . $newname . $file_name);
         }
         else
         {                                  // rename the file if another one exist
            $new_dir = "$desired_dir/" . $newname . $file_name;
            rename($file_tmp, $new_dir);
         }
      }
      else
      {
         print_r($errors);
      }
   }
   if (empty($error))
   {
      echo "FILE : $file1<br>";
      echo "FILE : $file2<br>";
      echo "FILE : $file3<br>";
      echo "FILE : $file4<br>";
      echo "FILE : $file5<br>";
   }
   $orig_directory = "$desired_dir";    //Full image folder
   $thumb_directory = "thumb/";    //Thumbnail folder

   /* Opening the thumbnail directory and looping through all the thumbs: */
   $dir_handle = @opendir($orig_directory); //Open Full image dirrectory
   if ($dir_handle > 1)
   { //Check to make sure the folder opened
      $allowed_types = array ('jpg', 'jpeg', 'gif', 'png');
      $file_type = array ();
      $ext = '';
      $title = '';
      $i = 0;

      while ($file_name = @readdir($dir_handle))
      {
         /* Skipping the system files: */
         if ($file_name == '.' || $file_name == '..')
            continue;

         $file_type = explode('.', $file_name);    //This gets the file name of the images
         $ext = strtolower(array_pop($file_type));

         /* Using the file name (withouth the extension) as a image title: */
         $title = implode('.', $file_type);
         $title = htmlspecialchars($title);

         /* If the file extension is allowed: */
         if (in_array($ext, $allowed_types))
         {

            /* If you would like to inpute images into a database, do your mysql query here */

            /* The code past here is the code at the start of the tutorial */
            /* Outputting each image: */

            $nw = 100;
            $nh = 100;
            $source = "$desired_dir{$file_name}";
            $stype = explode(".", $source);
            $stype = $stype[count($stype) - 1];
            $dest = "thumb/{$file_name}";

            $size = getimagesize($source);
            $w = $size[0];
            $h = $size[1];

            switch ($stype)
            {
               case 'gif':
                  $simg = imagecreatefromgif($source);
                  break;
               case 'jpg':
                  $simg = imagecreatefromjpeg($source);
                  break;
               case 'png':
                  $simg = imagecreatefrompng($source);
                  break;
            }

            $dimg = resizePreservingAspectRatio($simg, $nw, $nh);
            imagepng($dimg, $dest);
         }
      }

      /* Closing the directory */
      @closedir($dir_handle);
   }
}

function resizePreservingAspectRatio($img, $targetWidth, $targetHeight)
{
   $srcWidth = imagesx($img);
   $srcHeight = imagesy($img);

   // Determine new width / height preserving aspect ratio
   $srcRatio = $srcWidth / $srcHeight;
   $targetRatio = $targetWidth / $targetHeight;
   if (($srcWidth <= $targetWidth) && ($srcHeight <= $targetHeight))
   {
      $imgTargetWidth = $srcWidth;
      $imgTargetHeight = $srcHeight;
   }
   else if ($targetRatio > $srcRatio)
   {
      $imgTargetWidth = (int) ($targetHeight * $srcRatio);
      $imgTargetHeight = $targetHeight;
   }
   else
   {
      $imgTargetWidth = $targetWidth;
      $imgTargetHeight = (int) ($targetWidth / $srcRatio);
   }

   // Creating new image with desired size
   $targetImg = imagecreatetruecolor($targetWidth, $targetHeight);

   // Add transparency if your reduced image does not fit with the new size
   $targetTransparent = imagecolorallocate($targetImg, 255, 0, 255);
   imagefill($targetImg, 0, 0, $targetTransparent);
   imagecolortransparent($targetImg, $targetTransparent);

   // Copies image, centered to the new one (if it does not fit to it)
   imagecopyresampled(
      $targetImg, $img, ($targetWidth - $imgTargetWidth) / 2, // centered
      ($targetHeight - $imgTargetHeight) / 2, // centered
      0, 0, $imgTargetWidth, $imgTargetHeight, $srcWidth, $srcHeight
   );

   return $targetImg;
}

?>

<form method="post" enctype="multipart/form-data">
   <input name="files[]" type="file"/><br/>
   <input name="files[]" type="file"/><br/>
   <input name="files[]" type="file"/><br/>
   <input name="files[]" type="file"/><br/>
   <input name="files[]" type="file"/><br/>
   <input type="submit"/>
</form>

注意:我保存为PNG,就好像你想要一个100x100的图像使用非方形图像(例如800x600),并且在不破坏其纵横比的情况下,我们应该在未使用的空间后面加上透明度,JPEG不支持它。

【讨论】:

  • 对上面有点困惑,你想让我删除上面的调整大小代码或者我应该做什么???
  • 请帮我看看我的代码有什么错误,以便我的代码完美运行
  • 我告诉过你这个问题,你对目标图像的顶部/左侧水平位置使用负值。
  • 任何方式感谢表单帮助我检查问题我已经删除了某些代码表单问题,现在它可以正常工作会导致任何问题
  • 那我该怎么办你能纠正这部分吗if($w&gt; $h) { $adjusted_width = $w / $hm; $half_width = $adjusted_width / 2; $int_width = $w / $hm; imagecopyresampled($dimg,$simg,-$int_width,0,0,0,$adjusted_width,$nh,$w,$h); } else
【解决方案2】:

这是我上传多个文件并裁剪和裁剪它们的代码。

它将图像上传到一个文件夹,然后选择图像,裁剪它,重新上传裁剪的图像并删除原始图像。

我相信你可以玩这个

这是php代码

if(isset($_POST['upload_gal']))
{

$fk_id = $_POST['fk_id'];


$errors= array();
foreach($_FILES['files']['tmp_name'] as $key => $tmp_name ){
    $file_name = $key.$_FILES['files']['name'][$key];
    $file_size =$_FILES['files']['size'][$key];
    $file_tmp =$_FILES['files']['tmp_name'][$key];
    $file_type=$_FILES['files']['type'][$key];


   if($file_type=='image/jpeg'||$type=='image/gif'||$type=='image/bmp'||$type=='image/png')
             {
    $image_info = getimagesize($_FILES["files"]["tmp_name"][$key]);
    $image_width = $image_info[0];
    $image_height = $image_info[1];

                 $desired_dir="brand_images/";

    if(empty($errors)==true){
        if(is_dir($desired_dir)==false){
            mkdir("$desired_dir", 0755);        // Create directory if it does not exist
        }




            $locationing="brand_images/$file_name";
            move_uploaded_file($file_tmp,$locationing);


             $image = imagecreatefromstring(file_get_contents("brand_images/$file_name"));
        $rand = rand(111,43943749739349343);
        $filename = "brand_images/$rand-33$file_name";

         if($image_width >= 840 && $image_height >= 680)
        {
        $thumb_width = 1200;
        $thumb_height = 700;
        }else{
        $thumb_width = 800;
        $thumb_height = 533;
        }

        $width = imagesx($image);
        $height = imagesy($image);

        $original_aspect = $width / $height;
        $thumb_aspect = $thumb_width / $thumb_height;

        if ( $original_aspect >= $thumb_aspect )
        {
           // If image is wider than thumbnail (in aspect ratio sense)
           $new_height = $thumb_height;
           $new_width = $width / ($height / $thumb_height);
        }
        else
        {
           // If the thumbnail is wider than the image
           $new_width = $thumb_width;
           $new_height = $height / ($width / $thumb_width);
        }

        $thumb = imagecreatetruecolor( $thumb_width, $thumb_height );

        // Resize and crop
        imagecopyresampled($thumb,
               $image,
               0 - ($new_width - $thumb_width) / 2, // Center the image horizontally
               0 - ($new_height - $thumb_height) / 2, // Center the image vertically
               0, 0,
               $new_width, $new_height,
               $width, $height);
        imagejpeg($thumb, $filename, 80);

                                                       move_uploaded_file($tmp_name, $filename);


mysql_query("INSERT INTO gallery VALUES('','brand_images/$rand-33$file_name','$fk_id')");

        echo"<script>

 window.location = document.URL.replace(/#$/, '');

        </script>";
        }

这是html

<form action="" enctype="multipart/form-data"  method="POST">
       <h3 class="no_margin-top">Upload a new image</h3>
        <hr>
       <input type="hidden" name="fk_id" value="<?php echo $brand->brand_id ?>">
      <input name="upload_gal" type="submit" class="btn btn-sm pull-right btn-success" value="Upload">
     Upload image: <input type="file" name="files[]" multiple>
     <p class="text-danger top-buffer">If image is larger than 800x533, the image would be cropped</p>
  </form>

【讨论】:

  • 当我在那里处理表单或处理 5 张图像时,你能对你的代码做一些更改吗?它是如何工作的,我需要存储原始文件
  • 好的。我已经更改了删除原始文件的位。
  • 当您发布 5 张图片时。它会首先上传所有原始文件,然后选择每个文件并对其进行裁剪,然后使用此文件名“[RANDOM NUMBER]-33[FILE NAME]”保存裁剪后的文件。请记住将文件夹位置从“brand_images”更改为您的文件夹名称
  • @Eddy,如果 sanoj lawrence 和这个question 中的一样,那么他还不能适应一些代码。我在那里提供了一个完整的工作示例。
  • 哪个错误?在此处粘贴错误,以便我知道该怎么做
【解决方案3】:

以下代码将通过映射到正确的 imagecreatefrom* 函数或使用无效的图像类型抛出异常来解决问题。

switch(strtolower($stype)) {
            case 'gif':
                $simg = imagecreatefromgif($source);
                break;
            case 'jpg':
            case 'jpeg':
                $simg = imagecreatefromjpeg($source);
                break;
            case 'png':
                $simg = imagecreatefrompng($source);
                break;
            default:
            throw new \Exception('invalid image type :'.$stype);
            break;
        }

【讨论】:

    【解决方案4】:

    我认为选择 mime 类型比使用扩展更好。

    你会这样做:

    function check_supported_type($type)
    {
        switch($type)
        {
            case "image/jpeg":
            case "image/gif":
            case "image/png":
                return true;
            default:
                return false;
        }
    }
    
    function GetMimeType($file)
    {
        //$type = mime_content_type($file); //deprecated
    
        /* //file info -> normal method, but returns wrong values for ics files..
        $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
        $type = $filename.":".finfo_file($finfo, $filename);
        finfo_close($finfo);
        */
    
        $forbiddenChars = array('?', '*', ':', '|', ';', '<', '>');
    
        if(strlen(str_replace($forbiddenChars, '', $file)) < strlen($file))
            throw new \ArgumentException("Forbidden characters!");
    
        $file = escapeshellarg($file);
    
        ob_start();
        $type = system("file --mime-type -b ".$file);
        ob_clean();
    
        return $type;
    }
    

    像这样使用它:

    $file = "someimage.jpg";
    $mime = GetMimeType($file);
    if(check_supported_type($mime))
    {
       //do your image processing
    }
    

    希望对你有帮助

    编辑:

    也许你可以看看我的另一个答案:https://stackoverflow.com/a/26981319/3641016 那里你会看到如何生成拇指。

    编辑:

    添加了您编辑问题的答案:

    替换:

    $wm = $w/$nw;
    $hm = $h/$nw;
    $h_height = $nh/2;
    $w_height = $nw/2;
    
    if($w> $h) {
        $adjusted_width = $w / $hm;
        $half_width = $adjusted_width / 2;
        $int_width = $w / $hm;
        imagecopyresampled($dimg,$simg,-$int_width,0,0,0,$adjusted_width,$nh,$w,$h);
    } else {
        imagecopyresampled($dimg,$simg,0,0,0,0,$nw,$nh,$w,$h);
    }
    

    与:

    if($w > $h)
    {
        imagecopyresampled($dimg, $simg, 0,0, ($nw / $h * $w / 2 - $nw / 2),0, $nw,$nw, $h,$h);
    }
    else
    {
        imagecopyresampled($dimg, $simg, 0,0, 0,($nw / $w * $h / 2 - $nw / 2), $nw,$nw, $w,$w);
    }
    

    一切都应该没问题。 (如果拇指是二次方的)

    【讨论】:

    • 我需要新建图片处理或者上面的代码
    • 不,你不必创建新的图像处理代码,你可以用这个函数扩展你的代码
    • 如果它不起作用,你至少应该显示发生了什么错误,你尝试了什么等等。
    • 这很危险,因为您无法信任文件名(即,如果攻击者控制了文件名,则此处可能进行代码注入)
    • 你的意思是注入系统?我会看看如何摆脱这种情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-23
    • 2012-09-23
    • 2013-08-04
    • 1970-01-01
    相关资源
    最近更新 更多