0

我想在通过后台传输上传之前调整从手机图库中挑选的图像的大小到目前为止我有:-

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

    });
}

但是当我到达这一行时出现错误 return
file.openAsync(Windows.Storage.FileAccessMode.readWrite); 说我没有写权限?我如何获得写访问权或移动它以便我可以拥有写访问权?

4

1 回答 1

1

要调整图像大小,您可以使用 WinRT 中的图像编码 API,即 Windows.Graphics.Imaging 中的 API。我建议您查看简单成像示例 ( http://code.msdn.microsoft.com/windowsapps/Simple-Imaging-Sample-a2dec2b0 ) 的场景 2,它展示了如何对图像进行各种转换。那里包括更改尺寸,因此只需将不需要的部分切掉即可。

我在我的免费电子书Programming Windows Store Apps with HTML, CSS, and JavaScript, 2nd Edition中讨论了这一切,在第 13 章的“图像处理和编码”部分。在那里,我尝试将过程中的主要步骤分离成更容易消化的东西,并提供额外的样本。

编码过程看起来相当复杂(许多链接的承诺),但它非常简单,并且正是电子邮件程序为减少附加图像的大小所做的事情。在任何情况下,您都应该得到另一个带有较小图像的 StorageFile,然后您可以将其传递给上传者。我建议将您的临时应用数据用于此类文件,并确保在上传完成后清理它们。

于 2014-09-03T18:33:02.097 回答