php - 在使用 PHP 上传之前调整照片大小

标签 php file-upload upload html5-canvas image-uploading

我目前正在使用 Valums-File-Uploader 将文件上传到我的服务器。该插件使用 javascript 加载图像并使用 php 保存图像。缺点是它不会在上传照片之前调整照片大小;因此需要更多时间上传和使用更多资源。我遇到了一个 php 脚本,它实际上会重新调整图像的大小,但我不知道如何执行重新调整大小的部分并将其应用于 Valums 原始 file_uploader.php。由于我在 php 方面的经验有限,我想知道是否可以采用这种方法。我将列出这两个文件以供引用。

注意:有问题的 php 文件会重新调整图像大小并创建缩略图。调整大小功能是我感兴趣的功能。

提前致谢。

这是 Valums file_uploader.php

<?php
class qqUploadedFileXhr {
/**
 * Save the file to the specified path
 * @return boolean TRUE on success
 */
function save($path) {
    $input = fopen("php://input", "r");
    $temp = tmpfile();
    $realSize = stream_copy_to_stream($input, $temp);
    fclose($input);

    if ($realSize != $this->getSize()){
        return false;
    }

    $target = fopen($path, "w");
    fseek($temp, 0, SEEK_SET);
    stream_copy_to_stream($temp, $target);
    fclose($target);

    return true;
}
function getName() {
    return $_GET['qqfile'];
}
function getSize() {
    if (isset($_SERVER["CONTENT_LENGTH"])){
        return (int)$_SERVER["CONTENT_LENGTH"];
    } else {
        //throw new Exception('Getting content length is not supported.');
        return false;
    }
}
}


class qqUploadedFileForm {

function save($path) {
    if(!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)){
        return false;
    }
    return true;
}
function getName() {
    return $_FILES['qqfile']['name'];
}
function getSize() {
    return $_FILES['qqfile']['size'];
}
}

class qqFileUploader {
var $allowedExtensions = array();
var $sizeLimit = 10485760;
var $file;

function __construct(array $allowedExtensions = array(), $sizeLimit =   s10485760){
    $allowedExtensions = array_map("strtolower", $allowedExtensions);

    $this->allowedExtensions = $allowedExtensions;
    $this->sizeLimit = $sizeLimit;

    //$this->checkServerSettings();

    if (isset($_GET['qqfile'])) {
        $this->file = new qqUploadedFileXhr();
    } elseif (isset($_FILES['qqfile'])) {
        $this->file = new qqUploadedFileForm();
    } else {
        $this->file = false;
    }
}

function checkServerSettings(){
    $postSize = $this->toBytes(ini_get('post_max_size'));
    $uploadSize = $this->toBytes(ini_get('upload_max_filesize'));

    if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
        $size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
        die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
    }
}

function toBytes($str){
    $val = trim($str);
    $last = strtolower($str[strlen($str)-1]);
    switch($last) {
        case 'g': $val *= 1024;
        case 'm': $val *= 1024;
        case 'k': $val *= 1024;
    }
    return $val;
}

/**
 * Returns array('success'=>true, 'file'=>$filename) or array('error'=>'error message')
 */
function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
    if (!is_writable($uploadDirectory)){
        return array('error' => "Server error. Upload directory isn't writable.");
    }

    if (!$this->file){
        return array('error' => 'No files were uploaded.');
    }

    $size = $this->file->getSize();

    if ($size == 0) {
        return array('error' => 'File is empty');
    }

    if ($size > $this->sizeLimit) {
        return array('error' => 'File is too large');
    }

    $pathinfo = pathinfo($this->file->getName());
    $filename = strtolower($pathinfo['filename']);
    //$filename = md5(uniqid());
    $ext = strtolower($pathinfo['extension']);

    if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
        $these = implode(', ', $this->allowedExtensions);
        return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
    }

    if(!$replaceOldFile){
        /// don't overwrite previous files that were uploaded
        while (file_exists($uploadDirectory . $filename . '.' . $ext)) {
            $filename .= rand(10, 99);
        }
    }
    $filename = sanitize_file_name($filename);

    if ($this->file->save($uploadDirectory . $filename . '.' . $ext)){
        return array('success'=>true, 'file'=> $filename . '.' . $ext);
    } else {
        return array('error'=> 'Could not save uploaded file.' .
            'The upload was cancelled, or server error encountered');
}

}
}

这是我发现的在加载前调整图像大小的 php 脚本。

<?php
$thumb_square_size      = 200; //Thumbnails will be cropped to 200x200      pixels
$max_image_size         = 1100; //Maximum image size (height and width)
$thumb_prefix           = "thumb_"; //Normal thumb Prefix
$destination_folder     = 'C:\server\htdocs\UPLOAD\drag\uploads'; //upload      directory ends with / (slash)
$jpeg_quality           = 90; //jpeg quality
/continue only if $_POST is set and it is a Ajax request
if(isset($_POST) && isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&   strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'){

// check $_FILES['ImageFile'] not empty
if(!isset($_FILES['image_file']) || !is_uploaded_file($_FILES['image_file']['tmp_name'])){
        die('Image file is Missing!'); // output error when above checks fail.
}

//uploaded file info we need to proceed
$image_name = $_FILES['image_file']['name']; //file name
$image_size = $_FILES['image_file']['size']; //file size
$image_temp = $_FILES['image_file']['tmp_name']; //file temp

$image_size_info    = getimagesize($image_temp); //get image size

if($image_size_info){
    $image_width        = $image_size_info[0]; //image width
    $image_height       = $image_size_info[1]; //image height
    $image_type         = $image_size_info['mime']; //image type
}else{
    die("Make sure image file is valid!");
}

//switch statement below checks allowed image type 
//as well as creates new image from given file 
switch($image_type){
    case 'image/png':
        $image_res =  imagecreatefrompng($image_temp); break;
    case 'image/gif':
        $image_res =  imagecreatefromgif($image_temp); break;           
    case 'image/jpeg': case 'image/pjpeg':
        $image_res = imagecreatefromjpeg($image_temp); break;
    default:
        $image_res = false;
}

if($image_res){
    //Get file extension and name to construct new file name 
    $image_info = pathinfo($image_name);
    $image_extension = strtolower($image_info["extension"]); //image extension
    $image_name_only = strtolower($image_info["filename"]);//file name only, no extension

    //create a random name for new image (Eg: fileName_293749.jpg) ;
    $new_file_name = $image_name_only. '_' .  rand(0, 9999999999) . '.' . $image_extension;

    //folder path to save resized images and thumbnails
    $thumb_save_folder  = $destination_folder . $thumb_prefix . $new_file_name; 
    $image_save_folder  = $destination_folder . $new_file_name;

    //call normal_resize_image() function to proportionally resize image
    if(normal_resize_image($image_res, $image_save_folder, $image_type, $max_image_size, $image_width, $image_height, $jpeg_quality))
    {
        //call crop_image_square() function to create square thumbnails
        if(!crop_image_square($image_res, $thumb_save_folder, $image_type, $thumb_square_size, $image_width, $image_height, $jpeg_quality))
        {
            die('Error Creating thumbnail');
        }

        /* We have succesfully resized and created thumbnail image
        We can now output image to user's browser or store information in the database*/
        echo '<div align="center">';
        echo '<img src="uploads/'.$thumb_prefix . $new_file_name.'" alt="Thumbnail">';
        echo '<br />';
        echo '<img src="uploads/'. $new_file_name.'" alt="Resized Image">';
        echo '</div>';
    }

    imagedestroy($image_res); //freeup memory
}
}

#####  This function will proportionally resize image ##### 
function normal_resize_image($source, $destination, $image_type, $max_size,  $image_width, $image_height, $quality){

if($image_width <= 0 || $image_height <= 0){return false;} //return false if  nothing to resize

//do not resize if image is smaller than max size
if($image_width <= $max_size && $image_height <= $max_size){
    if(save_image($source, $destination, $image_type, $quality)){
        return true;
    }
}

//Construct a proportional size of new image
$image_scale    = min($max_size/$image_width, $max_size/$image_height);
$new_width      = ceil($image_scale * $image_width);
$new_height     = ceil($image_scale * $image_height);

$new_canvas     = imagecreatetruecolor( $new_width, $new_height ); //Create a new true color image

//Copy and resize part of an image with resampling
if(imagecopyresampled($new_canvas, $source, 0, 0, 0, 0, $new_width, $new_height, $image_width, $image_height)){
    save_image($new_canvas, $destination, $image_type, $quality); //save resized image
}

return true;
}

##### This function corps image to create exact square, no matter what its  original size! ######
function crop_image_square($source, $destination, $image_type, $square_size,   $image_width, $image_height, $quality){
if($image_width <= 0 || $image_height <= 0){return false;} //return false if  nothing to resize

if( $image_width > $image_height )
{
    $y_offset = 0;
    $x_offset = ($image_width - $image_height) / 2;
    $s_size     = $image_width - ($x_offset * 2);
}else{
    $x_offset = 0;
    $y_offset = ($image_height - $image_width) / 2;
    $s_size = $image_height - ($y_offset * 2);
}
$new_canvas = imagecreatetruecolor( $square_size, $square_size); //Create a new true color image

//Copy and resize part of an image with resampling
if(imagecopyresampled($new_canvas, $source, 0, 0, $x_offset, $y_offset, $square_size, $square_size, $s_size, $s_size)){
    save_image($new_canvas, $destination, $image_type, $quality);
}

return true;
}

##### Saves image resource to file ##### 
function save_image($source, $destination, $image_type, $quality){
switch(strtolower($image_type)){//determine mime type
    case 'image/png': 
        imagepng($source, $destination); return true; //save png file
        break;
    case 'image/gif': 
        imagegif($source, $destination); return true; //save gif file
        break;          
    case 'image/jpeg': case 'image/pjpeg': 
        imagejpeg($source, $destination, $quality); return true; //save jpeg file
        break;
    default: return false;
}
}

这是我的 MERGE 代码,但没有成功。

<?php
class qqUploadedFileXhr {
/**
 * Save the file to the specified path
 * @return boolean TRUE on success
 */
function save($path) {
    $input = fopen("php://input", "r");
    $temp = tmpfile();
    $realSize = stream_copy_to_stream($input, $temp);
    fclose($input);

    if ($realSize != $this->getSize()){
        return false;
    }

    $target = fopen($path, "w");
    fseek($temp, 0, SEEK_SET);
    stream_copy_to_stream($temp, $target);
    fclose($target);

    return true;
}
function getName() {
    return $_GET['qqfile'];
}
function getSize() {
    if (isset($_SERVER["CONTENT_LENGTH"])){
        return (int)$_SERVER["CONTENT_LENGTH"];
    } else {
        //throw new Exception('Getting content length is not supported.');
        return false;
    }
}
}
if($image_res){
    //Get file extension and name to construct new file name 
    $image_info = pathinfo($image_name);
    $image_extension = strtolower($image_info["extension"]); //image extension
    $image_name_only = strtolower($image_info["filename"]);//file name only, no extension

    //create a random name for new image (Eg: fileName_293749.jpg) ;
    $new_file_name = $image_name_only. '_' .  rand(0, 9999999999) . '.' . $image_extension;

    //folder path to save resized images and thumbnails
    $thumb_save_folder  = $destination_folder . $thumb_prefix . $new_file_name; 
    $image_save_folder  = $destination_folder . $new_file_name;

    //call normal_resize_image() function to proportionally resize image
    if(normal_resize_image($image_res, $image_save_folder, $image_type, $max_image_size, $image_width, $image_height, $jpeg_quality))
    {
        //call crop_image_square() function to create square thumbnails
        if(!crop_image_square($image_res, $thumb_save_folder, $image_type, $thumb_square_size, $image_width, $image_height, $jpeg_quality))
        {
            die('Error Creating thumbnail');
        }

        /* We have succesfully resized and created thumbnail image
        We can now output image to user's browser or store information in the database*/
        echo '<div align="center">';
        echo '<img src="uploads/'.$thumb_prefix . $new_file_name.'" alt="Thumbnail">';
        echo '<br />';
        echo '<img src="uploads/'. $new_file_name.'" alt="Resized Image">';
        echo '</div>';
    }

    imagedestroy($image_res); //freeup memory
}
}

#####  This function will proportionally resize image ##### 
function normal_resize_image($source, $destination, $image_type, $max_size,  $image_width, $image_height, $quality){

if($image_width <= 0 || $image_height <= 0){return false;} //return false if  nothing to resize

//do not resize if image is smaller than max size
if($image_width <= $max_size && $image_height <= $max_size){
    if(save_image($source, $destination, $image_type, $quality)){
        return true;
    }
}

//Construct a proportional size of new image
$image_scale    = min($max_size/$image_width, $max_size/$image_height);
$new_width      = ceil($image_scale * $image_width);
$new_height     = ceil($image_scale * $image_height);

$new_canvas     = imagecreatetruecolor( $new_width, $new_height ); //Create a new true color image

//Copy and resize part of an image with resampling
if(imagecopyresampled($new_canvas, $source, 0, 0, 0, 0, $new_width, $new_height, $image_width, $image_height)){
    save_image($new_canvas, $destination, $image_type, $quality); //save resized image
}

return true;
}

class qqUploadedFileForm {

function save($path) {
    if(!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)){
        return false;
    }
    return true;
}
function getName() {
    return $_FILES['qqfile']['name'];
}
function getSize() {
    return $_FILES['qqfile']['size'];
}
}

class qqFileUploader {
var $allowedExtensions = array();
var $sizeLimit = 10485760;
var $file;

function __construct(array $allowedExtensions = array(), $sizeLimit =   s10485760){
    $allowedExtensions = array_map("strtolower", $allowedExtensions);

    $this->allowedExtensions = $allowedExtensions;
    $this->sizeLimit = $sizeLimit;

    //$this->checkServerSettings();

    if (isset($_GET['qqfile'])) {
        $this->file = new qqUploadedFileXhr();
    } elseif (isset($_FILES['qqfile'])) {
        $this->file = new qqUploadedFileForm();
    } else {
        $this->file = false;
    }
}

function checkServerSettings(){
    $postSize = $this->toBytes(ini_get('post_max_size'));
    $uploadSize = $this->toBytes(ini_get('upload_max_filesize'));

    if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
        $size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
        die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
    }
}

function toBytes($str){
    $val = trim($str);
    $last = strtolower($str[strlen($str)-1]);
    switch($last) {
        case 'g': $val *= 1024;
        case 'm': $val *= 1024;
        case 'k': $val *= 1024;
    }
    return $val;
}

/**
 * Returns array('success'=>true, 'file'=>$filename) or array('error'=>'error message')
 */
function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
    if (!is_writable($uploadDirectory)){
        return array('error' => "Server error. Upload directory isn't writable.");
    }

    if (!$this->file){
        return array('error' => 'No files were uploaded.');
    }

    $size = $this->file->getSize();

    if ($size == 0) {
        return array('error' => 'File is empty');
    }

    if ($size > $this->sizeLimit) {
        return array('error' => 'File is too large');
    }

    $pathinfo = pathinfo($this->file->getName());
    $filename = strtolower($pathinfo['filename']);
    //$filename = md5(uniqid());
    $ext = strtolower($pathinfo['extension']);

    if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
        $these = implode(', ', $this->allowedExtensions);
        return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
    }

    if(!$replaceOldFile){
        /// don't overwrite previous files that were uploaded
        while (file_exists($uploadDirectory . $filename . '.' . $ext)) {
            $filename .= rand(10, 99);
        }
    }
    $filename = sanitize_file_name($filename);

    if ($this->file->save($uploadDirectory . $filename . '.' . $ext)){
        return array('success'=>true, 'file'=> $filename . '.' . $ext);
    } else {
        return array('error'=> 'Could not save uploaded file.' .
            'The upload was cancelled, or server error encountered');
}

}
}

最佳答案

php-image-resize , 你可以根据需要调整大小。 这是 fork 的 Valums-File-Uploader使用php-image-resize : https://github.com/turutosiya/30207227

<?php
/****************************************
Example of how to use this uploader class...
You can uncomment the following lines (minus the require) to use these as your defaults.
// list of valid extensions, ex. array("jpeg", "xml", "bmp")
$allowedExtensions = array();
// max file size in bytes
$sizeLimit = 10 * 1024 * 1024;
require('valums-file-uploader/server/php.php');
$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
// Call handleUpload() with the name of the folder, relative to PHP's getcwd()
$result = $uploader->handleUpload('uploads/');
// to pass data through iframe you will need to encode all html tags
echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
/******************************************/
require_once 'src/php-image-resize/src/ImageResize.php';
/**
 * Handle file uploads via XMLHttpRequest
 */
class qqUploadedFileXhr {
    private static $HEIGHT_TO_RESIZE = 500;
    /**
     * Save the file to the specified path
     * @return boolean TRUE on success
     */
    function save($path) {    
        $input = fopen("php://input", "r");
        $temp = tmpfile();
        $realSize = stream_copy_to_stream($input, $temp);
        fclose($input);

        if ($realSize != $this->getSize()){            
            return false;
        }
        $image = new ImageResize($temp);
        $image->resizeToHeight(self::$HEIGHT_TO_RESIZE);
        $image->save($path);

        return true;
    }
    function getName() {
        return $_GET['qqfile'];
    }
    function getSize() {
        if (isset($_SERVER["CONTENT_LENGTH"])){
            return (int)$_SERVER["CONTENT_LENGTH"];            
        } else {
            throw new Exception('Getting content length is not supported.');
        }      
    }   
}
/**
 * Handle file uploads via regular form post (uses the $_FILES array)
 */
class qqUploadedFileForm {  
    /**
     * Save the file to the specified path
     * @return boolean TRUE on success
     */
    function save($path) {
        $image = new ImageResize($_FILES['qqfile']['tmp_name']);
        $image->resizeToHeight(self::$HEIGHT_TO_RESIZE);
        $image->save($path);
        return true;
    }
    function getName() {
        return $_FILES['qqfile']['name'];
    }
    function getSize() {
        return $_FILES['qqfile']['size'];
    }
}
class qqFileUploader {
    private $allowedExtensions = array();
    private $sizeLimit = 10485760;
    private $file;
    function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){        
        $allowedExtensions = array_map("strtolower", $allowedExtensions);

        $this->allowedExtensions = $allowedExtensions;        
        $this->sizeLimit = $sizeLimit;

        $this->checkServerSettings();       
        if (isset($_GET['qqfile'])) {
            $this->file = new qqUploadedFileXhr();
        } elseif (isset($_FILES['qqfile'])) {
            $this->file = new qqUploadedFileForm();
        } else {
            $this->file = false; 
        }
    }

    public function getName(){
        if ($this->file)
            return $this->file->getName();
    }

    private function checkServerSettings(){        
        $postSize = $this->toBytes(ini_get('post_max_size'));
        $uploadSize = $this->toBytes(ini_get('upload_max_filesize'));        

        if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
            $size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';             
            die("{'error':'increase post_max_size and upload_max_filesize to $size'}");    
        }        
    }

    private function toBytes($str){
        $val = trim($str);
        $last = strtolower($str[strlen($str)-1]);
        switch($last) {
            case 'g': $val *= 1024;
            case 'm': $val *= 1024;
            case 'k': $val *= 1024;        
        }
        return $val;
    }

    /**
     * Returns array('success'=>true) or array('error'=>'error message')
     */
    function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
        if (!is_writable($uploadDirectory)){
            return array('error' => "Server error. Upload directory isn't writable.");
        }

        if (!$this->file){
            return array('error' => 'No files were uploaded.');
        }

        $size = $this->file->getSize();

        if ($size == 0) {
            return array('error' => 'File is empty');
        }

        if ($size > $this->sizeLimit) {
            return array('error' => 'File is too large');
        }

        $pathinfo = pathinfo($this->file->getName());
        $filename = $pathinfo['filename'];
        //$filename = md5(uniqid());
        $ext = @$pathinfo['extension'];     // hide notices if extension is empty
        if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
            $these = implode(', ', $this->allowedExtensions);
            return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
        }

        if(!$replaceOldFile){
            /// don't overwrite previous files that were uploaded
            while (file_exists($uploadDirectory . $filename . '.' . $ext)) {
                $filename .= rand(10, 99);
            }
        }

        if ($this->file->save($uploadDirectory . $filename . '.' . $ext)){
            return array('success'=>true);
        } else {
            return array('error'=> 'Could not save uploaded file.' .
                'The upload was cancelled, or server error encountered');
        }

    }    
}

关于php - 在使用 PHP 上传之前调整照片大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30207227/

相关文章:

asp.net-mvc-2 - 使用 Jquery 表单插件上传图像在 IE8 中不起作用

linux - 每次上传新文件时出现 403 Forbidden 错误

php://input 大文件失败

php - Doctrine 和 Symfony2 : How to execute raw queries (General error: 2014 Cannot execute queries while > other unbuffered queries are active)

php - 获取 404 页面的原始 url

python - 在 Django 中使用 AJAX 将正在进行的上传状态返回到 HTML 时遇到问题

javascript - JS 文件大小测试在多个文件上传时失败,但在单个文件上传时失败

php - Doctrine ORM 异常

php - fusionchart 不显示图表

node.js - 文件上传到 sails 时出现 res.forbidden 错误