Некоторое время назад я написал код для изменения размера изображения в современном приложении WinJS с пользовательским интерфейсом с помощью WinRT API.
Теперь меня также просят изменить разрешение изображения на 2,7-кратное его большую сторону (не спрашивайте).
Проблема в том, что я не могу найти правильный способ — если он существует — установить разрешение изображения с помощью WinRT.
Вот код до сих пор. Обратите внимание, что он учитывает изображения с несколькими кадрами (например, GIF).
function resizePictureAsync(file) {
const MAX_HEIGHT = 1600,
MAX_WIDTH = 1600,
RATIO_FOR_TWO_COLUMN_WORD_FIT = 2.7;
var inStream = null, outStream = null;
return file.openAsync(Windows.Storage.FileAccessMode.read).then(function (stream) {
inStream = stream;
return Windows.Graphics.Imaging.BitmapDecoder.createAsync(stream);
}).then(function (decoder) {
return Windows.Storage.ApplicationData.current.temporaryFolder.createFileAsync("temp-picture-resize", Windows.Storage.CreationCollisionOption.replaceExisting).then(function (resizedFile) {
return resizedFile.openAsync(Windows.Storage.FileAccessMode.readWrite).then(function (stream) {
outStream = stream;
return Windows.Graphics.Imaging.BitmapEncoder.createForTranscodingAsync(outStream, decoder);
}).then(function (encoder) {
var framesMasterPromise = WinJS.Promise.wrap(null);
for (var i = 0; i < decoder.frameCount; i++) {
(function (i) {
framesMasterPromise = framesMasterPromise.then(function () {
return decoder.getFrameAsync(i).then(function (bitmapFrame) {
return bitmapFrame.getPixelDataAsync().then(function (pixelDataContainer) {
var pixelData = pixelDataContainer.detachPixelData();
var newWidth = bitmapFrame.orientedPixelWidth,
newHeight = bitmapFrame.orientedPixelHeight;
if (bitmapFrame.orientedPixelWidth > MAX_WIDTH || bitmapFrame.orientedPixelHeight > MAX_HEIGHT) {
if (bitmapFrame.orientedPixelWidth > bitmapFrame.orientedPixelHeight) {
newWidth = MAX_WIDTH;
newHeight = Math.round(MAX_HEIGHT * bitmapFrame.orientedPixelHeight / bitmapFrame.orientedPixelWidth);
} else {
newWidth = Math.round(MAX_WIDTH * bitmapFrame.orientedPixelWidth / bitmapFrame.orientedPixelHeight);
newHeight = MAX_HEIGHT;
}
}
var biggestSide = Math.max(newWidth, newHeight);
var dpiForBothSides = biggestSide / RATIO_FOR_TWO_COLUMN_WORD_FIT;
encoder.setPixelData(
bitmapFrame.bitmapPixelFormat,
bitmapFrame.bitmapAlphaMode,
bitmapFrame.orientedPixelWidth,
bitmapFrame.orientedPixelHeight,
dpiForBothSides/*bitmapFrame.dpiX*/,
dpiForBothSides/*bitmapFrame.dpiY*/,
pixelData
);
encoder.bitmapTransform.scaledWidth = newWidth;
encoder.bitmapTransform.scaledHeight = newHeight;
if (i >= decoder.frameCount - 1)
return encoder.flushAsync();
return encoder.goToNextFrameAsync();
});
});
});
})(i);
}
return framesMasterPromise;
}).then(function () {
if (inStream) inStream.close();
if (outStream) outStream.close();
return resizedFile;
});
});
});
}
setPixelData() кажется единственным методом, который принимает разрешение, но он не влияет на результирующее изображение. На самом деле, я могу удалить всю часть encoder.setPixelData(...) и не увидеть никаких изменений.
getPixelDataAsync() может принимать дополнительные параметры, но это не помогает.
Спасибо за любую помощь, которую вы могли бы предоставить.