Angularjs сжимает изображение перед загрузкой

Я запускаю веб-сайт для мобильных устройств, который использует angular -file-upload.min.js для загрузки изображений из библиотеки изображений мобильных устройств.

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>

код:

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

Загрузка осуществляется очень медленно в мобильных устройствах. Как сжать файл?

Ответ 1

Упорядочить изображение в текстовом формате base-64 все хорошо и хорошо, но это займет немного времени и, конечно же, не сжимает его. На самом деле это, вероятно, будет заметно больше, чем исходное изображение. К сожалению, ваш браузер также не будет загружать файлы. Конечно, они могут обрабатывать загружаемые файлы. Вы могли бы попытаться сделать gzip самого текста, используя некоторое чистое решение JS. Глядя на github, вы можете найти такие вещи - https://github.com/beatgammit/gzip-js Однако это займет некоторое время, и нет гарантии, что версия сжатого текста изображения меньше, чем необработанный JPEG, который вы прикрепляете.

Собственное мобильное приложение может решить использовать некоторую встроенную оптимизацию кода JPEG или PNG перед отправкой (в основном, resample the image), если это необходимо, но выполнение этого в JavaScript кажется потенциально проблематичным на данный момент времени. Учитывая закон Этвуда (написания всего в конечном счете в JavaScript), это, безусловно, можно было бы сделать, но на данный момент в середине 2014 года это не так.

Ответ 2

Вы можете попытаться сохранить изображение на холсте, а затем преобразовать в data64 и затем загрузить строку данных. Я сделал это в POC, theres ошибка в 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);
    };
  }, 
}

Ответ 4

В качестве альтернативы программному решению - если ваше изображение создается камерой устройства для загрузки, то почему бы просто не изменить разрешение камеры. Наименьшее разрешение может быть в 10 раз меньше самого большого, и это может быть подходящим для многих ситуаций.