tamaño - editar imagenes con javascript
cambiar el tamaño de la imagen antes de cargarla mediante transferencia de fondo en winjs (1)
Para cambiar el tamaño de una imagen, puede usar las API de codificación de imágenes en WinRT, es decir, en Windows.Graphics.Imaging. Le sugiero que mire el escenario 2 de la muestra de imágenes simples ( http://code.msdn.microsoft.com/windowsapps/Simple-Imaging-Sample-a2dec2b0 ) que muestra cómo hacer todas las formas de transformaciones en una imagen. Cambiar las dimensiones está incluido allí, por lo que solo será cuestión de cortar las partes que no necesita.
Tengo una discusión sobre todo esto en mi libro electrónico gratuito, Programación de aplicaciones Windows Store con HTML, CSS y JavaScript, segunda edición , en el Capítulo 13, sección "Manipulación y codificación de imágenes". Intento separar los principales pasos del proceso en algo un poco más digerible y proporcionar una muestra adicional.
El proceso de codificación puede parecer bastante complicado (muchas promesas encadenadas), pero es bastante sencillo y es exactamente lo que haría un programa de correo electrónico para reducir el tamaño de las imágenes adjuntas, por ejemplo. En cualquier caso, debe terminar con otro StorageFile con una imagen más pequeña que luego puede pasar al cargador. Recomiendo usar los datos de la aplicación temporal para dichos archivos, y asegúrese de limpiarlos cuando se complete la carga.
Me gustaría cambiar el tamaño de una imagen elegida de la galería del teléfono antes de subirla mediante transferencia de fondo hasta ahora. Tengo:
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);
});
}
y el resto luego carga el archivo. Intenté agregar .slice pero no funciona (estoy adivinando porque el archivo es un objeto en lugar de) y no estoy seguro de cómo comprimir este tipo de objeto de archivo. Parece que no puedo encontrar ejemplos o consejos sobre msdn o los foros de desarrollo de Windows, obviamente puedo cambiar el tamaño de las fotos una vez que están en el servidor, pero preferiría que los usuarios no esperaran más de lo necesario para cargar sus archivos.
¿Debo guardar la imagen antes de poder manipularla? ¡Cualquier consejo sería muy apreciado!
** EDIT *
mi subida singlefileasync ahora se ve así: -
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);
});
}
Pero recibo un error cuando alcanzo esta línea
file.openAsync (Windows.Storage.FileAccessMode.readWrite); diciendo que no tengo acceso de escritura? ¿Cómo obtengo acceso de escritura o lo muevo para que pueda tener acceso de escritura?