canvas = {
const ny = imgHeight / tileSize
const w = nx * tileSize
const h = ny * tileSize
const context = DOM.context2d(w, h)
context.drawImage(await img, -dx * tileSize, 0)
const imageData = context.getImageData(0, 0, w * devicePixelRatio, h * devicePixelRatio)
const tiles = []
const mapData = context.createImageData(nx, ny)
let mapIndex = 0
for(let y = 0; y < ny; y ++) {
for(let x = 0; x < nx; x ++) {
const tileData = context.createImageData(tileSize * devicePixelRatio, tileSize * devicePixelRatio)
let tileIndex = 0
let tileID = ''
let average = [0, 0, 0]
for(let yy = 0; yy < tileSize * devicePixelRatio; yy ++) {
for(let xx = 0; xx < tileSize * devicePixelRatio; xx ++) {
const pixelX = x * tileSize * devicePixelRatio + xx
const pixelY = y * tileSize * devicePixelRatio + yy
const pixelIndex = (pixelY * (w * devicePixelRatio) + pixelX) * 4
for(let i = 0; i < 4; i++) {
tileData.data[tileIndex ++] = imageData.data[pixelIndex + i]
if(xx > 0 && xx < tileSize * devicePixelRatio - 1 &&
yy > 0 && yy < tileSize * devicePixelRatio - 1 && i < 3) {
average[i] += imageData.data[pixelIndex + i]
if(xx % 2 == 0 && yy % 2 == 0) tileID += imageData.data[pixelIndex + i].toString(36)
}
}
}
}
average = average.map(d => d / ((tileSize * devicePixelRatio - 2) ** 2) | 0)
let c = tiles.findIndex(tile => tile.tileID === tileID)
if(c === - 1) {
tiles.push({ tileData, tileID })
c = tiles.length - 1
}
mapData.data[mapIndex] = c
mapData.data[mapIndex + 1] = c
mapData.data[mapIndex + 2] = c
mapData.data[mapIndex + 3] = 255
mapIndex += 4
}
}
const image = new Image()
image.style.border = 'solid 1px red'
image.src = context.canvas.toDataURL('image/png')
image.mapData = mapData
image.tiles = tiles
return image
}