Unable to create thumb, image is black

前端 未结 4 1530
花落未央
花落未央 2021-01-26 03:27

Am uploading Multiple image from single input and create thumb form all uploaded image on fly But when i run code i get only black image but orginal image is same as upl

相关标签:
4条回答
  • 2021-01-26 04:04

    Problem

    The problem is located in the following line:

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

    Why are you using a negative value as destination's x? Your source image is actually put at the left of your target image, so your target image appears empty.

    Solution

    I invite you to use the following function to resize your image:

    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;
    }
    

    Implementation

    <?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>
    

    Note: I am saving as PNG, as if you want a 100x100 image using a non-square image (such as 800x600), and without breaking its aspect ratio, we should put transparency behind the unused space and JPEG do not support it.

    0 讨论(0)
  • 2021-01-26 04:07

    The following code will solve the problem by mapping to the correct imagecreatefrom* function or throw an exception with the invalid image type.

    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;
            }
    
    0 讨论(0)
  • 2021-01-26 04:07

    I think it's better to go for the mime type than the extension.

    You'll do this:

    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;
    }
    

    use it like this:

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

    hope this helps

    EDIT:

    Maybe you can take a look at my other answer: https://stackoverflow.com/a/26981319/3641016 there you'll see how to generate thumbs.

    EDIT:

    added the answer to your editet question:

    replace:

    $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);
    }
    

    with:

    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);
    }
    

    and everything should be ok. (if the thumb is quadratic)

    0 讨论(0)
  • 2021-01-26 04:15

    This is my code for uploading multiple files and cropping and cropping them.

    It uploads the image to a folder, then picks the image, crops it , re-uploads the cropped image and deletes the original image.

    Am sure you can play around with this

    This is the php code

    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>";
            }
    

    This is the 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>
    
    0 讨论(0)
提交回复
热议问题