Last active
July 3, 2020 02:14
-
-
Save shts/1c75fe2113233804db6d15df114834a4 to your computer and use it in GitHub Desktop.
透過pngの透過位置の座標を検出して矩形で囲むサンプル。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="ja"> | |
<head> | |
<meta charset="utf-8"> | |
<title>タイトル</title> | |
</head> | |
<body> | |
<div style="display: flex"> | |
<input type="file" id="input" onchange="handleFiles(this.files)"> | |
<button onClick="searchTranslationRect()"> | |
Search | |
</button> | |
</div> | |
<div style="display: flex"> | |
<img id="image" width="300" alt="" src=""> | |
<p id="pos"></p> | |
</div> | |
<p id="loading" style="display: none">Loading...</p> | |
<!--suppress JSCheckFunctionSignatures --> | |
<script> | |
class Rect { | |
constructor(x, y, dx, dy) { | |
this.x = x; | |
this.y = y; | |
this.dx = dx; | |
this.dy = dy; | |
} | |
} | |
function showLoading() { | |
document.getElementById('loading').style.display = 'block' | |
} | |
function hideLoading() { | |
document.getElementById('loading').style.display = 'none' | |
} | |
function handleFiles(files) { | |
showLoading(); | |
const canvas = document.createElement('canvas'); | |
const context = canvas.getContext('2d'); | |
(async () => { | |
const image = await loadImage(files[0]); | |
// Canvas サイズを画像サイズに拡大 | |
canvas.width = image.width; | |
canvas.height = image.height; | |
// Canvas上に画像を表示 | |
context.drawImage(image, 0, 0, image.width, image.height); | |
console.log('search start'); | |
const rect = await searchTranslationRect(canvas); | |
console.log('search end', rect); | |
// 矩形情報を表示する | |
// context.beginPath(); | |
context.strokeStyle = 'red'; | |
context.lineWidth = 10; | |
context.rect(rect.x, rect.y, rect.dx - rect.x, rect.dy - rect.y); | |
context.stroke(); | |
let data = canvas.toDataURL(); | |
document.getElementById('image').setAttribute('src', data); | |
document.getElementById('pos').textContent = `開始座標(${rect.x}, ${rect.y}) 横(${rect.dx - rect.x}) 縦(${rect.dy - rect.y})` | |
hideLoading(); | |
})() | |
} | |
async function loadImage(file) { | |
const image = new Image(); | |
return new Promise((resolve, reject) => { | |
const reader = new FileReader(); | |
reader.onload = (e) => { | |
image.onload = () => { | |
resolve(image) | |
} | |
image.onerror = e => reject(e) | |
// noinspection JSValidateTypes | |
image.src = e.target.result | |
} | |
reader.readAsDataURL(file) | |
}) | |
} | |
async function searchTranslationRect(canvas) { | |
// TODO 複数の矩形を返す | |
return new Promise((resolve, reject) => { | |
const context = canvas.getContext('2d'); | |
let imageWidth = canvas.width; | |
let imageHeight = canvas.height; | |
let minX = Number.MAX_VALUE; | |
let minY = Number.MAX_VALUE; | |
let maxX = Number.MIN_VALUE; | |
let maxY = Number.MIN_VALUE; | |
for (let x = 0; x < imageWidth; x++) { | |
for (let y = 0; y < imageHeight; y++) { | |
const data = context.getImageData(x, y, 1, 1).data; | |
if (data[0] === 0 && data[1] === 0 && data[2] === 0 && data[3] === 0) { | |
// rgba が全て 0 の透過ピクセルなら座標を保存する | |
minX = Math.min(minX, x); | |
minY = Math.min(minY, y); | |
maxX = Math.max(maxX, x); | |
maxY = Math.max(maxY, y); | |
} | |
} | |
} | |
resolve(new Rect(minX, minY, maxX, maxY)); | |
}); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment