supports img smaller than tile size
This commit is contained in:
79
src/image.ts
79
src/image.ts
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user