javascript angularjs 在上传前压缩图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23246861/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 00:37:04  来源:igfitidea点击:

angularjs compress image before upload

javascriptangularjshtmlfile-uploadcompression

提问by ben ezra

I'm buliding a web site for mobile devices, that uses angular-file-upload.min.js for uploading images from a mobile device image library.

我正在为移动设备构建一个网站,该网站使用 angular-file-upload.min.js 从移动设备图像库上传图像。

html code:

html代码:

<div>
    <div class="rating-camera-icon">
        <input type="file" accept="image/*" name="file" ng-file-
         select="onFileSelect($files)">
    </div>
    <img ng-show="fileName" ng-src="server/{{fileName}}" width="40"
     style="margin-left:10px">
</div>

code:

代码:

$scope.onFileSelect = function($files) {
        for (var i = 0; i < $files.length; i++) {
            var file = $files[i];
            if (!file.type.match(/image.*/)) {
                // this file is not an image.
            };
            $scope.upload = $upload.upload({
                url: BASE_URL + 'upload.php',
                data: {myObj: $scope.myModelObj},
                file: file
            }).progress(function(evt) {
                    // console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
                    // $scope.fileProgress = evt.loaded / evt.total * 100.0;
                }).success(function(data, status, headers, config) {
                    // file is uploaded successfully
                    $scope.fileName = data;
                });
        }
    };

The upload is very slow in mobile devices. How can I compress the file?

移动设备上的上传速度非常慢。如何压缩文件?

回答by TAP

Stringifying the image into a base-64 text format is all fine and well, but it will take a small amount of time and certainly does not compress it. In fact it will likely be noticeably larger than the raw image. Unfortunately your browser will also not gzip an uploads. They can of course handle gzipped downloads. You could certainly try to do a gzip of the text itself using some pure JS solution. Looking on github you can find such things - https://github.com/beatgammit/gzip-jsHowever, that will take some time as well and there is no guarantee that the compressed text version of the image is any smaller than the raw JPEG you attach.

将图像字符串化为 base-64 文本格式完全没有问题,但它会花费少量时间并且肯定不会压缩它。事实上,它可能会明显大于原始图像。不幸的是,您的浏览器也不会 gzip 上传。他们当然可以处理 gzip 下载。您当然可以尝试使用一些纯 JS 解决方案对文本本身进行 gzip。在 github 上你可以找到这样的东西 - https://github.com/beatgammit/gzip-js但是,这也需要一些时间,并且不能保证图像的压缩文本版本比原始图像小您附加的 JPEG。

A native mobile app might decide to use some native code JPEG or PNG optimization before sending (basically resample the image) if appropriate, but doing this out in JavaScript seems potentially problematic at this point in time. Given Atwood's law (of writing everything eventually in JavaScript) it certainly could be done but at this point in mid-2014 it isn't.

如果合适,本机移动应用程序可能会决定在发送之前使用一些本机代码 JPEG 或 PNG 优化(基本上重新采样图像),但在 JavaScript 中执行此操作在此时看来可能存在问题。鉴于阿特伍德定律(最终用 JavaScript 编写所有内容),这当然可以完成,但在 2014 年年中的这一点上还不是。

回答by Santiago Rebella

You could try to store the image on a canvas, then convert to data64 and then upload the data string. I made kind of this in a POC, theres a bug in ios regarding large images as the one you could take with the camera when in canvas, but the overal works nice... something like;

您可以尝试将图像存储在画布上,然后转换为 data64,然后上传数据字符串。我在 POC 中做了这样的事情,ios 中有一个关于大图像的错误,因为你可以在画布中用相机拍摄的图像,但整体效果很好......像这样;

file = files[0];
try {
  var URL = window.URL || window.webkitURL,
      imgURL = URL.createObjectURL(file);
  showPicture.src = imgURL;
  imgBlobToStore = imgURL;
  if(AppData.supports_html5_storage()) {      
    var canvas = document.getElementById('storingCanvas') ,
        ctx = canvas.getContext('2d'),
        img = new Image(),
        convertedFile;
    img.src = imgBlobToStore;
    img.onload = function () {    
        canvas.width = img.width;
        canvas.height= img.height;
        ctx.drawImage(img, 0,0,img.width, img.height);
        convertedFile = canvas.toDataURL("image/jpeg"); //or png
        //replace with angular storage here
        localStorage.setItem( $('.pic').attr('id'), convertedFile);
    };
  }, 
}

回答by Roger Layton

As an alternative to a programmatic solution - if your image is being created by the device camera for upload, then why not simply change the resolution of the camera. The smallest resolution may be 10x smaller than the largest, and this may be suitable for many situations.

作为程序化解决方案的替代方案 - 如果您的图像是由设备相机创建用于上传,那么为什么不简单地更改相机的分辨率。最小分辨率可能比最大分辨率小 10 倍,这可能适用于许多情况。