Skip to content

Instantly share code, notes, and snippets.

@shts
Last active July 3, 2020 02:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shts/1c75fe2113233804db6d15df114834a4 to your computer and use it in GitHub Desktop.
Save shts/1c75fe2113233804db6d15df114834a4 to your computer and use it in GitHub Desktop.
透過pngの透過位置の座標を検出して矩形で囲むサンプル。
<!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