Geometry & Pixel Art Engine
グリッド・サンプリングと
幾何学的な刺繍再現技術
「刺繍」というアナログな質感をデジタルで再現するために必要なのは、単なるピクセル化ではありません。グリッドごとの代表色を正確に抽出するサンプリング技術と、キャンバス座標を動的に「×」印のパスへと変換する描画ロジックの裏側を解説します。
1. 中心座標オフセットによるピクセルサンプリング
画像をクロスステッチ風にする際、単純な縮小・拡大(Nearest Neighbor)ではエッジが汚くなってしまうことがあります。本ツールでは、指定された「ステッチの大きさ(グリッド)」の中央付近から色情報を取得するサンプリング手法を採用しています。
メリット: グリッド全体を平均化するよりも、色と色の境界線が刺繍らしく「パキッ」と分かれます。また、背景の白い布地を活かすために、特定以上の輝度を持つピクセルを「無色」としてスキップするガードレールを設けています。
// ステッチ中央のピクセルデータを取得するロジック
for(let y = 0; y < canvasHeight; y += stitchSize) {
for(let x = 0; x < canvasWidth; x += stitchSize) {
// グリッドの中央座標を特定
const targetX = x + Math.floor(stitchSize / 2);
const targetY = y + Math.floor(stitchSize / 2);
// 独自のオフセット計算でImageData配列から色を抽出
const i = (targetY * canvasWidth + targetX) * 4;
const r = pixels[i], g = pixels[i+1], b = pixels[i+2];
// 独自の輝度閾値判定により、布地を透かす処理
if (isBackground(r, g, b)) continue;
// 抽出した色でステッチを描画
drawCross(x, y, r, g, b);
}
} 2. 幾何学的な「×」印(ステッチパス)の構築
刺繍の質感は、2本の糸が交差する瞬間に生まれます。本ツールでは、塗りつぶしの四角形を置くのではなく、Canvasの stroke を用いて2本の対角線を順次描画しています。
メリット: スライダーで調整可能な「糸の太さ」を lineWidth に反映させるだけで、繊細な刺繍から力強い刺繍まで表現が変化します。また、ステッチ同士の間にわずかな余白(パディング)を動的に計算して設けることで、糸の重なりと布の隙間をシミュレートしています。
// 1つのステッチを描画するパス生成
const padding = stitchSize * // 独自の余白係数;
ctx.lineWidth = stitchSize * // 選択された糸の太さ係数;
ctx.lineCap = 'round'; // 糸の端を丸めて柔らかさを出す
ctx.beginPath();
// 1本目の糸: 左上から右下へ
ctx.moveTo(x + padding, y + padding);
ctx.lineTo(x + stitchSize - padding, y + stitchSize - padding);
// 2本目の糸: 右上から左下へ
ctx.moveTo(x + stitchSize - padding, y + padding);
ctx.lineTo(x + padding, y + stitchSize - padding);
ctx.stroke(); 3. モバイル端末向けの「MAX_SIZE」リサイズ・パイプライン
クロスステッチの描画は、グリッド数に比例して Canvas への stroke 命令数が激増します(例えば 100x100 のグリッドなら 2万回の線描画)。最新スマホの高解像度写真をそのまま処理すると、ブラウザの描画スレッドが飽和してクラッシュする恐れがあります。
メリット: 読み込み時にアスペクト比を維持したまま、安全な上限解像度(1500px程度)へダウンサンプリングする工程を挟むことで、低スペックなデバイスでも「刺繍中...」のままフリーズすることなく、安定して画像を生成できます。
// 高負荷描画に耐えるためのリサイズ処理
const MAX_SAFE_RES = // 独自のパフォーマンス制限値;
if (img.width > MAX_SAFE_RES || img.height > MAX_SAFE_RES) {
const scale = // 独自の縮小比率算出;
const targetW = img.width * scale;
const targetH = img.height * scale;
// 一時Canvasで縮小画像を焼き付け
// この縮小済みデータを「色情報のソース」として使用
// ...
} Developer's Note
このツールで一番大切にしたのは、ドット絵としての正確さよりも「刺繍としての不完全さ」です。
当初はグリッドを隙間なく埋めていましたが、それだとただのドット絵にしか見えませんでした。そこで、あえてステッチ(×印)の間に布地が見える余白をコンマ数ミリ単位で調整し、さらに糸の端を round 指定で丸めることで、刺繍糸特有の柔らかい膨らみを表現しました。
また、iPhoneユーザーの方が HEIC 形式を意識せずそのままドロップして使えるよう、ブラウザ内変換を組み込んでいます。機密性の高い写真を一歩も外に出さず、あなたの端末の中で「かわいい作品」へと昇華させる。その一連の流れを JavaScript だけで完結させることにこだわりました。