supports img smaller than tile size

This commit is contained in:
xororz
2024-10-19 21:52:38 +08:00
parent 37036998d3
commit 76f23dade3
2 changed files with 80 additions and 9 deletions

View File

@@ -20,15 +20,76 @@ export default class Image {
x2: number,
y2: number
) {
for (let j = y1; j < y2; j++) {
for (let i = x1; i < x2; i++) {
let index = (y + j - y1) * this.width * 4 + (x + i - x1) * 4;
let imageIndex = j * image.width * 4 + i * 4;
this.data[index] = image.data[imageIndex];
this.data[index + 1] = image.data[imageIndex + 1];
this.data[index + 2] = image.data[imageIndex + 2];
this.data[index + 3] = image.data[imageIndex + 3];
}
const width = x2 - x1;
for (let j = 0; j < y2 - y1; j++) {
const destIndex = (y + j) * this.width * 4 + x * 4;
const srcIndex = (y1 + j) * image.width * 4 + x1 * 4;
this.data.set(
image.data.subarray(srcIndex, srcIndex + width * 4),
destIndex
);
}
}
padToTileSize(tileSize: number) {
let newWidth = this.width;
let newHeight = this.height;
if (this.width < tileSize) {
newWidth = tileSize;
}
if (this.height < tileSize) {
newHeight = tileSize;
}
if (newWidth === this.width && newHeight === this.height) {
return;
}
const newData = new Uint8Array(newWidth * newHeight * 4);
for (let y = 0; y < this.height; y++) {
const srcStart = y * this.width * 4;
const destStart = y * newWidth * 4;
newData.set(
this.data.subarray(srcStart, srcStart + this.width * 4),
destStart
);
}
if (newWidth > this.width) {
const rightColumnIndex = (this.width - 1) * 4;
for (let y = 0; y < this.height; y++) {
const destRowStart = y * newWidth * 4;
const srcPixelIndex = y * this.width * 4 + rightColumnIndex;
const padPixel = this.data.subarray(srcPixelIndex, srcPixelIndex + 4);
for (let x = this.width; x < newWidth; x++) {
const destPixelIndex = destRowStart + x * 4;
newData.set(padPixel, destPixelIndex);
}
}
}
if (newHeight > this.height) {
const bottomRowStart = (this.height - 1) * newWidth * 4;
const bottomRow = newData.subarray(
bottomRowStart,
bottomRowStart + newWidth * 4
);
for (let y = this.height; y < newHeight; y++) {
const destRowStart = y * newWidth * 4;
newData.set(bottomRow, destRowStart);
}
}
this.width = newWidth;
this.height = newHeight;
this.data = newData;
}
cropToOriginalSize(width: number, height: number) {
const newData = new Uint8Array(width * height * 4);
for (let y = 0; y < height; y++) {
const srcStart = y * this.width * 4;
const destStart = y * width * 4;
newData.set(
this.data.subarray(srcStart, srcStart + width * 4),
destStart
);
}
this.width = width;
this.height = height;
this.data = newData;
}
}

View File

@@ -37,6 +37,13 @@ self.addEventListener("message", async (e) => {
return;
}
const input = new Img(data.width, data.height, new Uint8Array(data.input));
const width_ori = input.width;
const height_ori = input.height;
input.padToTileSize(data?.tile_size || 64);
let withPadding = false;
if (input.width !== width_ori || input.height !== height_ori) {
withPadding = true;
}
let hasAlpha = data.hasAlpha;
function sendprogress(progress) {
if (hasAlpha) {
@@ -223,6 +230,9 @@ self.addEventListener("message", async (e) => {
} catch (e) {
postMessage({ alertmsg: e.toString() });
}
if (withPadding) {
output.cropToOriginalSize(width_ori * factor, height_ori * factor);
}
const end = Date.now();
console.log("Time:", end - start);
await new Promise((resolve) => setTimeout(resolve, 10));