Я пишу приложение в JavaScript UWP для обрезки сторон изображения, обрезки левого и самого правого пикселей, которые прозрачны в png.
У меня есть функция, которую я написал, которая правильно читает байты и находит левую и правую границу изображения - например, если первый непрозрачный пиксель имеет 100 пикселей, а последний не -прозрачный - 200 пикселей, он возвращает объект, который выглядит как {leftBound: 100, rightBound: 200, height: 50, width: 300}
.
Так что моя проблема заключается в сохранении нового изображения с этими границами. Единственный пример кода, который я смог найти, был этот код в c # . Поэтому я попытался следовать этому, вот так:
async function processImage(stream) {
const calcBounds = await getPixelBounds(stream.cloneStream());
const transform = new Windows.Graphics.Imaging.BitmapTransform();
transform.bounds.x = calcBounds.leftBound;
transform.bounds.width = calcBounds.rightBound - calcBounds.leftBound;
transform.bounds.height = calcBounds.height;
transform.scaledHeight = transform.bounds.height;
transform.scaledWidth = transform.bounds.width;
const decoder = await Windows.Graphics.Imaging.BitmapDecoder.createAsync(stream);
const pixelFormat = decoder.bitmapPixelFormat;
const alphaMode = decoder.bitmapAlphaMode;
const dpiX = decoder.dpiX;
const dpiY = decoder.dpiY;
const data = await decoder.getPixelDataAsync(
pixelFormat,
alphaMode,
transform,
Windows.Graphics.Imaging.ExifOrientationMode.respectExifOrientation,
Windows.Graphics.Imaging.ColorManagementMode.colorManageToSRgb
);
const pixels = data.detachPixelData();
const outputFilename = "cropped.png";
const encoderId = Windows.Graphics.Imaging.BitmapEncoder.pngEncoderId;
const folder = Windows.Storage.ApplicationData.current.localFolder;
const outputFile =
await folder.createFileAsync(outputFilename,
Windows.Storage.CreationCollisionOption.openIfExists);
const outputStream = await outputFile.openAsync(Windows.Storage.FileAccessMode.readWrite);
outputStream.size = 0;
const encoder = await Windows.Graphics.Imaging.BitmapEncoder.createAsync(encoderId, outputStream);
encoder.setPixelData(
pixelFormat,
alphaMode,
calcBounds.rightBound - calcBounds.leftBound,
calcBounds.height,
dpiX,
dpiY,
pixels
);
await encoder.flushAsync();
stream && stream.close();
outputStream && outputStream.close();
}
Первое, что я заметил при отладке, это то, что свойства transform.bounds
не менялись. На самом деле я почти уверен, что это моя основная проблема, и весь код может быть исправлен, если я пойму, как установить transform.bounds
.
Я попытался просто создать новый объект, transform.bounds = {x:0, y:0, width: 0, height: 0}
, а затем сбросить ширину и высоту, как я делаю в коде позже, но это не сработало.
В примере c # он использует new Windows.Graphics.Imaging.BitmapBounds()
, но этого не существует в javascript ...
[править]
Я попробовал это:
const transform = new Windows.Graphics.Imaging.BitmapTransform();
const bounds = { x: 0, y: 0, width: 0, height: 0 };
bounds.x = calcBounds.leftBound;
bounds.width = calcBounds.rightBound - calcBounds.leftBound;
bounds.height = calcBounds.height;
transform.bounds = bounds;
Но это вызывает исключение в строке, где я делаю const data = await decoder.getPixelDataAsync(...
, говоря, что параметр неверен