上传前调整图片大小

4
我正在编写HTML+JS代码,以便在自动提交表单到服务器之前先调整图片大小。我最初为自动提交表单编写了代码,然后添加了图像调整逻辑。自动提交表单可以正常工作,但是图像调整不能正常工作。请提供指导。谢谢您的帮助。
<!DOCTYPE html>
<html>
<head>
<title>Flask App</title>    
<meta name="viewport" content="width=device-width, initial-scale=1, user-
scalable=no">  
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script> 
<script src="http://malsup.github.com/jquery.form.js"></script> 

<script type="text/javascript">
$(function(){
    //JS Code snippet 1 - Automatic form submission on file selection
    $("#file_select").change(function(){
    $("#upload_form").submit();  
    $("#upload_form_div").hide();
    $("#loading").show();

    //JS Code snippet 2 - Image Resizing
    var filesToUpload = inputs.files;

    var img = document.createElement("img");
    var reader = new FileReader();  
    reader.onload = function(e) {img.src = e.target.result}
    reader.readAsDataURL(file);

    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);

    var MAX_WIDTH = 800;
    var MAX_HEIGHT = 600;
    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 xhr = new XMLHttpRequest();
    xhr.open("POST", "upload");
    xhr.send(ctx.toDataURL());

});
});

 </script>

 </head>

 <body>
  <h1 class="logo">Upload Picture</h1>
  <div id="upload_form_div">
   <form id="upload_form" method="POST" enctype="multipart/form-data" action="upload">
    <input type="file" name="file" capture="camera" id="file_select"/>
   </form>
  </div>

  <div id="loading" style="display:none;"> 
     Uploading your picture...
  </div>

 </body>
</html>

更新 - (2014年3月28日) -合并了@yuhua和“上传者”功能的代码JIC库。更新后的代码如下:

当我在笔记本电脑的Chrome浏览器中打开我的Web应用程序时,一切正常。但是,当我通过在iPhone 4s上使用Chrome浏览器打开我的Web应用程序来上传照片时,我的调整大小的图像并未按预期显示出来。请查看下面的原始图像和调整大小后的图像。请纠正我做错的地方。

$("#file_select").change(function (e) {
 var fileReader = new FileReader();
 fileReader.onload = function (e) {
    var img = new Image();
    img.onload = function () {
        var MAX_WIDTH = 3264;
        var MAX_HEIGHT = 2448;
        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;
            }
        }

        var canvas = document.createElement("canvas");
        canvas.width = width;
        canvas.height = height;
        canvas.getContext("2d").drawImage(this, 0, 0, width, height);

        this.src = canvas.toDataURL();
        //document.body.appendChild(this);//remove this if you don't want to show it

        var newImageData = canvas.toDataURL("image/png", 70/100);
         var result_image_obj = new Image();
         result_image_obj.src = newImageData;

          //======= Step 2 - Upload compressed image to server =========

          //Here we set the params like endpoint, var name (server side) and filename
          var server_endpoint = 'upload',
              server_var_name = 'file',
              filename = "new.jpg";

          //This is the callback that will be triggered once the upload is completed
          var callback = function(response){ console.log(response); }

          //Here goes the magic
          $("#result").load(jic.upload(result_image_obj, server_endpoint, server_var_name, filename, callback));



    }
    img.src = e.target.result;
    console.log(img);

}
fileReader.readAsDataURL(e.target.files[0]);
});

Original Image Resized Image being uploaded to server

2个回答

5
我认为您的浏览器可能不支持 .mozGetAsFile() 。我修改了您的代码,下面是一个示例:
$("#file_select").change(function (e) {
    var fileReader = new FileReader();
    fileReader.onload = function (e) {
        var img = new Image();
        img.onload = function () {
            var MAX_WIDTH = 100;
            var MAX_HEIGHT = 100;
            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;
                }
            }

            var canvas = document.createElement("canvas");
            canvas.width = width;
            canvas.height = height;
            canvas.getContext("2d").drawImage(this, 0, 0, width, height);
            this.src = canvas.toDataURL();
            document.body.appendChild(this);//remove this if you don't want to show it
        }
        img.src = e.target.result;
    }
    fileReader.readAsDataURL(e.target.files[0]);
});

这是一个参考链接:如何将HTML5画布输出为图像?

更新:

请查看页面底部(浏览器支持)。 https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement

我尝试了你的解决方案,它将调整大小后的图像附加到文档末尾。太好了!我正在尝试完成下一步,即将此调整大小后的图像通过“POST”发送到“/upload”。在你的片段结尾处,我在fileReader.readAsDataURL之后添加了以下代码,但它没有提交表单。你能指导一下吗? fileReader.onloadend = function () { var xhr = new XMLHttpRequest(); xhr.open("POST", "upload"); xhr.send(fileReader);} - user1146904
尝试使用以下代码:xhr.open("POST", "upload", true); - yuhua
也许你可以尝试使用$.ajax()代替xhr,并在最后一行调用表单提交:$("#upload_form").submit(); - yuhua
我使用了JIC的AJAX上传函数进行上传。现在我能够调整大小并上传,但是调整大小后的图像效果不如预期。请查看我的更新代码。 - user1146904
你的代码是正确的,这是由于EXIF图像引起的iPhone相机的棘手问题。这里是参考链接:https://dev59.com/DWYr5IYBdhLWcg3wE2Wz - yuhua

-1
你可以尝试使用PHP而不是HTML和JavaScript。我们正在做的是将调整大小后的图像路径存储到数据库中。
public function Resize_image($width = 0, $height = 0, $quality = 90, $filename_in = null, $filename_out = null)
{
    $this->Filename = $filename_in;
    $this->Extension = strtolower($this->Get_file_extension($this->Filename));

    $size = getimagesize($this->Filename);
    $ratio = $size[0] / $size[1];
    if ($ratio >= 1){
        $scale = $width / $size[0];
    } else {
        $scale = $height / $size[1];
    }
    // make sure its not smaller to begin with!
    if ($width >= $size[0] && $height >= $size[1]){
        $scale = 1;
    }

    // echo $fileext;
    switch ($this->Extension)
    {
        case "jpg":
            $im_in = imagecreatefromjpeg($this->Filename);
            $im_out = imagecreatetruecolor($size[0] * $scale, $size[1] * $scale);
            imagecopyresampled($im_out, $im_in, 0, 0, 0, 0, $size[0] * $scale, $size[1] * $scale, $size[0], $size[1]);
            imagejpeg($im_out, $filename_out, $quality);
        break;
        case "gif":
            $im_in = imagecreatefromgif($this->Filename);
            $im_out = imagecreatetruecolor($size[0] * $scale, $size[1] * $scale);
            imagecopyresampled($im_out, $im_in, 0, 0, 0, 0, $size[0] * $scale, $size[1] * $scale, $size[0], $size[1]);
            imagegif($im_out, $filename_out, $quality);
        break;
        case "png":
            $im_in = imagecreatefrompng($this->Filename);
            $im_out = imagecreatetruecolor($size[0] * $scale, $size[1] * $scale);
            imagealphablending($im_in, true); // setting alpha blending on
            imagesavealpha($im_in, true); // save alphablending setting (important)
            imagecopyresampled($im_out, $im_in, 0, 0, 0, 0, $size[0] * $scale, $size[1] * $scale, $size[0], $size[1]);
            imagepng($im_out, $filename_out, 9);
        break;
    }
    imagedestroy($im_out);
    imagedestroy($im_in);
}

现在,您可以像这样使用此函数来调整图像大小并将其复制到所需的目录中。
Resize_image($width, $height, $quality=90, $filename_in, $filename_out)

例如:

Resize_image(150, 150, 90, "Directory".$image, "Directory".$image_without_extension."_thumb.".$image_ext); //makes file_thumb.ext

你的代码片段是为图像设置CSS,而不是生成新的调整大小的图像。如果我错了,请纠正我。 - user1146904

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接