代码之家  ›  专栏  ›  技术社区  ›  Marco

php上载前使用FileReader调整多个图像大小

  •  0
  • Marco  · 技术社区  · 7 年前

    我有一个很好的php多上传脚本(还有一点javascript)。 问题是,用户直接从相机拍照,因此图像尺寸太大,而移动带宽太小。

    因此,我搜索了一个解决方案来调整图像客户端的大小,并找到了一些与FileReader和canvas相关的帖子。

    我的问题是如何用php上载脚本上载filereader的“结果”。

    这就是我所拥有的:

    HTML:

    <input id="fileupload" type="file" name="images[]" multiple/>
    

    用于动态添加上载字段和预览上载的Javascript:

    var abc = 0; 
    $(document).ready(function() {
    $('#add-file-field').click(function() {
     $("#newrow").append("<div class='col-sm-4'><div id='newrow' class='card'><div class='card-body'><input id='fileupload' type='file' name='images[]' multiple/></div></div></div>");
    });
    
    $('body').on('change', '#fileupload', function(){
      if (this.files && this.files[0]) {
           abc += 1; 
    
          var z = abc - 1;
          var x = $(this).parent().find('#previewimg' + z).remove();
          $(this).before("<div id='abcd"+ abc +"' class='card-img-top abcd'><img id='previewimg" + abc + "' src='' style='width:100%; height:100%;'/></div>");
    
          var reader = new FileReader();
          reader.onload = imageIsLoaded;
          reader.readAsDataURL(this.files[0]);
    
          $(this).hide();
    
          $("#abcd"+ abc).append($("<img/>", {id: 'delete', src: 'x.png', alt: 'delete'}).click(function() {
          $(this).parent().parent().parent().remove();
          }));
      }
    });
    //To preview image     
    function imageIsLoaded(e) {
          $('#previewimg' + abc).attr('src', e.target.result);
      };
      $('#upload').click(function(e) {
      var name = $(":file").val();
      if (!name)
      {
          alert("First Image Must Be Selected");
          e.preventDefault();
      }
      });
    });   
    

    以及Php脚本:

    $lastpositionid = $_SESSION['lastpositionid'];
    $query = "INSERT INTO media (posid,orderid,name,image,created,tag,type) VALUES('$lastpositionid',$position->order_id,?,?,'$date','Vorher',?)";
    $stmt = $con->prepare($query);
    
    if(isset($_FILES['images'])){
    
            $countfiles = count($_FILES['images']['name']);
            $target_directory = "../uploads/". $position->order_id;
    
            $file_upload_error_messages="";
    
            for($i=0;$i<$countfiles;$i++){
    
                if(!is_dir($target_directory)){
                   mkdir($target_directory, 0777, true);
                }
    
                $filename = $_FILES['images']['name'][$i];
                $shafilename = sha1_file($_FILES['images']['tmp_name'][$i]) . "-" . date('d-m-Y-H-i-s') . "-" . basename($_FILES["images"]["name"][$i]);
    
                $media->image = $filename[$i];
                $file_size = $_FILES['images']['size'][$i];
                $ext = end((explode(".", $filename)));
                $valid_ext = array('jpg','JPG','jpeg','JPEG','png','PNG','gif','GIF','mov','MOV','mp4','MP4');
    
    
            if(!empty($_FILES["images"]["tmp_name"][$i])){
    
                if($file_size > 104857600){
                    $file_upload_error_messages.= "<div class=\"alert alert-danger alert-dismissable\">";
                    $file_upload_error_messages.= "</div>";
                }   
    
                if(in_array($ext, $valid_ext)){
                   }
    
                   else{
                        $file_upload_error_messages.= "<div class=\"alert alert-danger alert-dismissable\">";
                        $file_upload_error_messages.= "</div>";
                   }
    
                if(!empty($file_upload_error_messages)){
                    $file_upload_error_messages.= "<div class=\"alert alert-danger alert-dismissable\">";
                    $file_upload_error_messages.= "</div>";
                }       
    
                if(empty($file_upload_error_messages)){
                        if(move_uploaded_file($_FILES['images']['tmp_name'][$i],$target_directory."/".$shafilename)){
                            echo "<div class=\"alert alert-success alert-dismissable\">";
                            echo "<button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">&times;</button>";
                            echo "</div>";
    
                                 // Execute query
                                 $stmt->execute(array($shafilename,'uploads/'.$position->order_id.'/'.$shafilename,$ext));
    
                    }
                }
            } 
        }
        print_r($file_upload_error_messages);
    }
    

    现在我想我可以使用这个脚本(或我在这里找到的类似脚本):

    function handleFiles()
    {
        var filesToUpload = document.getElementById('fileupload').files;
        var file = filesToUpload[0];
    
        // Create an image
        var img = document.createElement("img");
        // Create a file reader
        var reader = new FileReader();
        // Set the image once loaded into file reader
        reader.onload = function(e)
        {
            img.src = e.target.result;
    
            var canvas = document.createElement("canvas");
            //var canvas = $("<canvas>", {"id":"testing"})[0];
            var ctx = canvas.getContext("2d");
            ctx.drawImage(img, 0, 0);
    
            var MAX_WIDTH = 400;
            var MAX_HEIGHT = 300;
            var width = img.width;
            var height = img.height;
    
            if (width > height) {
              if (width > MAX_WIDTH) {
                height *= MAX_WIDTH / width;
                width = MAX_WIDTH;
              }
            } else {
              if (height > MAX_HEIGHT) {
                width *= MAX_HEIGHT / height;
                height = MAX_HEIGHT;
              }
            }
            canvas.width = width;
            canvas.height = height;
            var ctx = canvas.getContext("2d");
            ctx.drawImage(img, 0, 0, width, height);
    
            var dataurl = canvas.toDataURL("image/png");
            document.getElementById('image').src = dataurl;     
        }
        // Load files into file reader
        reader.readAsDataURL(file);
    }
    

    FileReader的脚本对我来说很清楚,除了如何用php再次上传的部分。顺便说一句,我对php比js更熟悉,另一个问题是如何在我现有的脚本中集成此功能。。。

    我没有外部上传脚本,它都在同一个php文件中。

    谢谢

    1 回复  |  直到 7 年前
        1
  •  3
  •   I wrestled a bear once.    7 年前

    您不能在客户端收缩图像并将其上载为文件,但可以收缩图像,然后获取shurnken图像的dataURI并将其上载为字符串,然后在服务器端将其转换回图像。

    var maxWidth = 100;
    var maxHeight = 100;
    
    document.getElementById("myfile").onchange = function() {
      var reader = new FileReader();
      reader.onload = function(e) {
        var img = new Image();
        img.onload = function() {
          var cnvs = document.createElement('canvas');
          var rectRatio = img.width / img.height;
          var boundsRatio = maxWidth / maxHeight;
          var w, h;
          if (rectRatio > boundsRatio) {
            w = maxWidth;
            h = img.height * (maxWidth / img.width);
          } else {
            w = img.width * (maxHeight / img.height);
            h = maxHeight;
          }
          cnvs.width = w;
          cnvs.height = h;
          var ctx = cnvs.getContext('2d');
          ctx.drawImage(img, 0, 0, w, h);
          var uri = cnvs.toDataURL();
          // Do something here to upload the smaller verion of the datauri
          // for now i'm just putting it on the page though
          document.body.innerHTML = '<img src="' + uri + '">';
        };
        img.src = e.target.result;
      };
      reader.readAsDataURL(this.files[0]);
    }
    <input type=file id=myfile accept=".png">

    然后在PHP端,您可以将其保存为如下实际图像

    $data = $_POST['mydatauri'];
    $encodedData = str_replace(' ','+',substr($data,strpos($data,",")+1));
    $decodedData = base64_decode($encodedData);
    file_put_contents("myUploadImage.png", $decodedData);