ピクセル画像を描画するCanvasのサンプルコード
プリアンブル
紅白歌合戦で遊んだ子供時代。特にあの頃の国産ジークが記憶に残っている。
マリオの奴思い出した。
子供の頃からドット絵のゲームが特に好きだったこともあり、ドット絵のスタイル自体は極めてシンプルな要素で構成された極めて複雑な絵なので、創作の余地が無限にあり、結果として忘れられない独特の画風になるのだと思います。そこで、大量生産用にピクセル・ドット・マトリックスで画像を生成するために、わかりやすい絵を借用したいと考えたのです。
初めて書いた短い記事なので、いろいろと至らない点があることをご容赦ください。
はじめに
クリア画像をピクセル調の画像に変換する方法とは?
まず理解しておかなければならないのは、ピクセルスタイルは単純な1色のブロックで構成されているということです。
そこで、まず画像をアップロードして、それを描画します。次に、画像を解析して色の値を取得し、各ピクセルの位置を決定します。そして、色値をキャンバスの対応する位置に再描画します。これが、ピクセルウィンドを簡単に実装する方法です。
実装方法
1. 元画像をアップロードする
<input type="file" accept=".jpeg,.jpg,.png" />
<script>
document.querySelector("input[type=file]").addEventListener("change",uploadImage, false);
</script>
まず、ファイルをアップロードするための入力をページに配置し、accept属性を使ってアップロードの種類を制限する必要があります。ここでは、jpeg、jpg、pngといった通常の画像のアップロードが含まれるためです。
また、変換が必要なファイルを取得するために、変更をリッスンします。
次にuploadImage関数を定義してみます。
function uploadImage(e) {
let file = e.target.files[0];
if (!file) return;
let fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = () => {
createImage(fileReader);
e.target.value = "";
document.querySelectorAll("canvas").forEach(node=>{node.remove();})
};
}
function createImage(obj) {
let img = new Image();
img.onload = () => {
drawImage(img);
};
img.src = obj.result;
}
ここでは、アップロードされた画像のアドレスを fileReader.result で取得し、createImage 関数を書いて、Image としてインスタンス化されたファイルオブジェクトを受け取って canvas に描画しています。結局のところ、1つの関数で1つのことしかできないようにするのが良い習慣なのです。
2. 元画像を描画する
function drawImage(img) {
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
canvas.width = ctx.width;
canvas.height = ctx.height
let w = img.width,
h = img.height;
ctx.drawImage(img,0,0,w,h);
document.body.appendChild(canvas);
}
まず、画像をキャンバスに描画することを同時に実装してみましょう。具体的にはどのようなものでしょうか。今度は、どれくらいの大きさのピクセル画を生成したいかを考えます。ここでは、グローバル変数を作りたい、と思っています。
let width = 32;
let height = 32;
let size = 10;
生成する幅、高さ、ピクセルサイズを定義しています。widthとheightはその名の通り、幅が何ピクセルで高さが何ドットのものを生成したいかを示している。sizeはピクセルがどのくらいの大きさで塗りつぶされるかを示しており、サイズピクセルごとに色の値が取られている。
次に、drawImage関数を変形してみましょう。
function drawImage(img) {
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
canvas.width = ctx.width = width * size;
canvas.height = ctx.height = height * size;
let w = img.width,
h = img.height;
let v = w / h;
if (v > 1) {
w = width;
h = w / v;
} else {
h = height;
w = h * v;
}
ctx.drawImage(
img,
((width - w) / 2) * size,
((height - h) / 2) * size,
w * size,
h * size
);
document.body.appendChild(canvas);
let pxMap = createPxMap(ctx);
drawPXCanvas(pxMap)
}
画像を描画し、ピクセル情報を含む配列のセットを生成して返すことを想定し、ピクセル風の生成を行います。
もちろん、2つの画像を比較するために、元の画像の幅と高さもピクセル画像で水平にし、キャンバスの中央に配置しました。
3. ピクセルアートの描画
function createPxMap(ctx){
let pxMap = [];
for (let i = 0; i < width * size; i += size) {
for (let j = 0; j < height * size; j += size) {
let pixel = ctx.getImageData(i, j, 1, 1).data;
let color = `rgba(${pixel[0]},${pixel[1]},${pixel[2]},${pixel[3]/255})`;
pxMap.push({ x: i / size, y: j / size, color });
}
}
return pxMap;
}
まず、点の位置と色の情報を取得したいと思います。 ctx.getImageDataは、それぞれ赤、緑、青、透明度の情報を表すビット0〜3のバッファの配列を取得します。この情報を格納したい。
最後はいよいよピクセルの絵が描けるようになるのです。
function drawPXCanvas(pxMap) {
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
canvas.width = ctx.width = width * size;
canvas.height = ctx.height = height * size;
pxMap.forEach((px) => {
const { color, x, y } = px;
ctx.fillStyle = color;
ctx.fillRect(x*size, y*size, size, size);
});
document.body.appendChild(canvas);
}
キャンバスを再生成して、先ほど収集したピクセル情報を一つずつキャンバスに描画していくので、簡単なピクセルペイントが出来上がります、簡単でしょう?
拡大する
実は、ピクセル情報を取得すると、canvas2dのピクセルペインティングを超えることができるんです。
また、次のような考え方もあります。
cssのbox-shadowを使ってピクセルアートを生成し、using: rootやscssを使ってサイズや位置を簡単に制御し、animationを使ってアニメーションを生成することができます。
webglを拡張して、3Dピクセルや他のスタイルを生成することもできます。
そして、ピクセル化された構図をフレーム単位でドリルダウンして解析し、動画やアニメーションを生成することができるのです。
Canvasでピクセル画像を描画するサンプルコードの紹介は以上となります。Canvas のピクセル化コンテンツに関する詳細については、スクリプトハウスの過去記事を検索するか、以下の関連記事を引き続きご覧ください。
関連
-
HTML5 ドラッグ&ドロップによるファイルアップロードのサンプルコード
-
localStorageの最大記憶容量を取得する方法を説明する
-
Html5ページオープンアプリに関するいくつかの考察
-
9ボックスグリッドの原則を用いたHTMLページレイアウト
-
HTML5 Canvasタグの解説と基本的な使い方
-
HTML表示 pdf, word, xls, ppt方式例
-
html5モバイル価格入力キーボードの実装
-
キャンバスを使用して、実装の画像にタイル状の透かしを追加することを教える手
-
IOSキーボードがfocusoutイベントでしまわれたときに元の場所に戻らない問題を解決する
-
モバイルhtml5で長押しイベントをシミュレートする方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
キャンバスは、マウスがまぶしい小さなボールの実装に従ってください。
-
HTML5で音声や動画を読み込むためのコード
-
iframeタグが入れ子になっている問題の解決法
-
HTML5 Blobによるファイルダウンロード機能のサンプルコード
-
html5でhotcss.jsを使い、携帯電話の自己適合を実現する方法
-
HTML5 における scroll-to-bottom イベントの問題を解決する方法
-
h5 web透かしSDKの実装コード例
-
キャンバスの描画は、contain または cover モードで適応され、中央に配置されます。
-
Canvas がクロスドメイン画像を導入し、toDataURL() エラーが発生する。
-
HTML5ページシームレス点滅オープン問題と解決策