Javascript 在winjs中通过后台传输上传前调整图像大小

Javascript 在winjs中通过后台传输上传前调整图像大小,javascript,windows-phone-8.1,winjs,win-universal-app,background-transfer,Javascript,Windows Phone 8.1,Winjs,Win Universal App,Background Transfer,在通过背景传输上传之前,我想调整从手机多媒体资料中拾取的图像的大小。到目前为止,我有:- filePicker.pickSingleFileAsync().then(function (file) { uploadSingleFileAsync(uri, file); }).done(null, displayException); function uploadSingleFileAsyn

在通过背景传输上传之前,我想调整从手机多媒体资料中拾取的图像的大小。到目前为止,我有:-

filePicker.pickSingleFileAsync().then(function (file) {
                            uploadSingleFileAsync(uri, file);
                        }).done(null, displayException);

function uploadSingleFileAsync(uri, file) {
                    if (!file) {
                        displayError("Error: No file selected.");
                        return;
                    }
                    return file.getBasicPropertiesAsync().then(function (properties) {
                        if (properties.size > maxUploadFileSize) {
                            displayError("Selected file exceeds max. upload file size (" + (maxUploadFileSize / (1024 * 1024)) +
                                " MB).");
                            return;
                        }
                        var upload = new UploadOperation();
                        //tried this to compress the file but it doesnt work obviously not right for the object
                        //file = file.slice(0, Math.round(file.size / 2));
                        upload.start(uri, file);
                        // Persist the upload operation in the global array.
                        uploadOperations.push(upload);
                    });
                }
其余的则上传文件。我尝试添加了.slice,但它不起作用(我猜是因为文件是一个对象而不是一个对象),我不确定如何压缩这种类型的文件对象。我似乎在msdn或windows开发论坛上找不到任何示例或建议,我可以在照片放在服务器上后调整其大小,但我希望用户不要等待文件上传的时间过长

我需要先保存图像,然后才能操作它吗?任何建议都将不胜感激

**编辑*

我的上载singlefileasync现在看起来像:-

function uploadSingleFileAsync(uri, file) {
                    if (!file) {
                        displayError("Error: No file selected.");
                        return;
                    }

                    return file.getBasicPropertiesAsync().then(function (properties) {
                        if (properties.size > maxUploadFileSize) {
                            displayError("Selected file exceeds max. upload file size (" + (maxUploadFileSize / (1024 * 1024)) +
                                " MB).");
                            return;
                        }







                        // Exception number constants. These constants are defined using values from winerror.h,
                        // and are compared against error.number in the exception handlers in this scenario.

                        // This file format does not support the requested operation; for example, metadata or thumbnails.
                        var WINCODEC_ERR_UNSUPPORTEDOPERATION = Helpers.convertHResultToNumber(0x88982F81);
                        // This file format does not support the requested property/metadata query.
                        var WINCODEC_ERR_PROPERTYNOTSUPPORTED = Helpers.convertHResultToNumber(0x88982F41);
                        // There is no codec or component that can handle the requested operation; for example, encoding.
                        var WINCODEC_ERR_COMPONENTNOTFOUND = Helpers.convertHResultToNumber(0x88982F50);
                        // Keep objects in-scope across the lifetime of the scenario.
                        var FileToken = "";
                        var DisplayWidthNonScaled = 0;
                        var DisplayHeightNonScaled = 0;
                        var ScaleFactor = 0;
                        var UserRotation = 0;
                        var ExifOrientation = 0;
                        var DisableExifOrientation = false;

                        // Namespace and API aliases
                        var FutureAccess = Windows.Storage.AccessCache.StorageApplicationPermissions.futureAccessList;
                        var LocalSettings = Windows.Storage.ApplicationData.current.localSettings.values;

                        //FileToken = FutureAccess.add(file);
                        FileToken = Windows.Storage.AccessCache.StorageApplicationPermissions.futureAccessList.add(file);

                        id("myImage").src = window.URL.createObjectURL(file, { oneTimeOnly: true });
                        id("myImage").alt = file.name;

                        // Use BitmapDecoder to attempt to read EXIF orientation and image dimensions.
                        return loadSaveFileAsync(file)


                        function resetPersistedState() {
                            LocalSettings.remove("scenario2FileToken");
                            LocalSettings.remove("scenario2Scale");
                            LocalSettings.remove("scenario2Rotation");
                        }
                        function resetSessionState() {
                            // Variables width and height reflect rotation but not the scale factor.
                            FileToken = "";
                            DisplayWidthNonScaled = 0;
                            DisplayHeightNonScaled = 0;
                            ScaleFactor = 1;
                            UserRotation = Windows.Storage.FileProperties.PhotoOrientation.normal;
                            ExifOrientation = Windows.Storage.FileProperties.PhotoOrientation.normal;
                            DisableExifOrientation = false;

                        }




                        function loadSaveFileAsync(file) {
    // Keep data in-scope across multiple asynchronous methods.
    var inputStream;
    var outputStream;
    var encoderId;
    var pixels;
    var pixelFormat;
    var alphaMode;
    var dpiX;
    var dpiY;
    var outputFilename;
    var ScaleFactor = 0.5;

    new WinJS.Promise(function (comp, err, prog) { comp(); }).then(function () {
        // On Windows Phone, this call must be done within a WinJS Promise to correctly
        // handle exceptions, for example if the file is read-only.
        return FutureAccess.getFileAsync(FileToken);

    }).then(function (inputFile) {
        return inputFile.openAsync(Windows.Storage.FileAccessMode.read);
    }).then(function (stream) {
        inputStream = stream;
        return Windows.Graphics.Imaging.BitmapDecoder.createAsync(inputStream);
    }).then(function (decoder) {
        var transform = new Windows.Graphics.Imaging.BitmapTransform();

        // Scaling occurs before flip/rotation, therefore use the original dimensions
        // (no orientation applied) as parameters for scaling.
        // Dimensions are rounded down by BitmapEncoder to the nearest integer.
        transform.scaledHeight = decoder.pixelHeight * ScaleFactor;
        transform.scaledWidth = decoder.pixelWidth * ScaleFactor;
        transform.rotation = Helpers.convertToBitmapRotation(UserRotation);

        // Fant is a relatively high quality interpolation mode.
        transform.interpolationMode = Windows.Graphics.Imaging.BitmapInterpolationMode.fant;

        // The BitmapDecoder indicates what pixel format and alpha mode best match the
        // natively stored image data. This can provide a performance and/or quality gain.
        pixelFormat = decoder.bitmapPixelFormat;
        alphaMode = decoder.bitmapAlphaMode;
        dpiX = decoder.dpiX;
        dpiY = decoder.dpiY;

        // Get pixel data from the decoder. We apply the user-requested transforms on the
        // decoded pixels to take advantage of potential optimizations in the decoder.
        return decoder.getPixelDataAsync(
            pixelFormat,
            alphaMode,
            transform,
            Windows.Graphics.Imaging.ExifOrientationMode.respectExifOrientation,
            Windows.Graphics.Imaging.ColorManagementMode.colorManageToSRgb
            );
    }).then(function (pixelProvider) {
        pixels = pixelProvider.detachPixelData();

        // The destination file was passed as an argument to loadSaveFileAsync().
        outputFilename = file.name;
        switch (file.fileType) {
            case ".jpg":
                encoderId = Windows.Graphics.Imaging.BitmapEncoder.jpegEncoderId;
                break;
            case ".bmp":
                encoderId = Windows.Graphics.Imaging.BitmapEncoder.bmpEncoderId;
                break;
            case ".png":
            default:
                encoderId = Windows.Graphics.Imaging.BitmapEncoder.pngEncoderId;
                break;
        }

        return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
    }).then(function (stream) {
        outputStream = stream;

        // BitmapEncoder expects an empty output stream; the user may have selected a
        // pre-existing file.
        outputStream.size = 0;
        return Windows.Graphics.Imaging.BitmapEncoder.createAsync(encoderId, outputStream);
    }).then(function (encoder) {
        // Write the pixel data onto the encoder. Note that we can't simply use the
        // BitmapTransform.ScaledWidth and ScaledHeight members as the user may have
        // requested a rotation (which is applied after scaling).
        encoder.setPixelData(
            pixelFormat,
            alphaMode,
            DisplayWidthNonScaled * ScaleFactor,
            DisplayHeightNonScaled * ScaleFactor,
            dpiX,
            dpiY,
            pixels
            );

        return encoder.flushAsync();
    }).then(function () {
        WinJS.log && WinJS.log("Successfully saved a copy: " + outputFilename, "sample", "status");
    }, function (error) {
        WinJS.log && WinJS.log("Failed to update file: " + error.message, "sample", "error");
        resetSessionState();
        resetPersistedState();
    }).then(function () {
        // Finally, close each stream to release any locks.
        inputStream && inputStream.close();
        outputStream && outputStream.close();
    }).then(function () {
        var upload = new UploadOperation();
        upload.start(uri, file);
        // Persist the upload operation in the global array.
        uploadOperations.push(upload);

    });
}
但是当我到达这一行返回时,我得到了一个错误
openAsync(Windows.Storage.FileAccessMode.readWrite);
说我没有写权限?如何获得写访问权限或移动它以获得写访问权限?

要调整图像大小,可以使用WinRT中的图像编码API,即Windows.Graphics.Imaging中的图像编码API。我建议您看看Simple Imaging Sample()的场景2,它展示了如何对图像进行所有方式的变换。更改尺寸包含在其中,因此只需切掉不需要的零件即可

我在我的免费电子书第13章“图像处理和编码”一节中讨论了这一切。在这里,我试图将过程中的主要步骤分离出来,使之更易于消化,并提供一个额外的样本


编码的过程可能看起来相当复杂(有很多连锁承诺),但它非常简单,而且正是电子邮件程序用来减少附加图像大小的方法。在任何情况下,您都应该得到另一个带有较小图像的StorageFile,然后可以将其传递给上传程序。我建议您使用这些文件的临时应用程序数据,并确保在上载完成后将其清理干净。

感谢我尝试了此示例,甚至这给了我一个错误:-SCRIPT16389:异常即将被第485行的JavaScript库代码捕获,第13列以毫秒为单位-appx://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/js/Scenario2_ImageTransforms.js 0x80004005-JavaScript运行时错误:未指定的错误文件:Scenario2_ImageTransforms.js,第485行,第13列,尝试在以下行重新保存图像:return FutureAccess.getFileAsync(FileToken);我认为这可能是一个只读类型的错误,这很奇怪。但是,FutureAccess只是为了保存对文件的权限,以便以后进行会话。如果要保存到具有固有权限的appdata,则不需要这样做。