エンジニアなので https://t.co/Z9AK16Lkmz で描きました #めそ子イラストコンテスト pic.twitter.com/wZkfUGkVUR
— ᓬᐓᔒᐓᓳᐓᔙᐓᓙᐓᓠᐓ (@razon) February 19, 2019
ご安全に!角田です。
めそ子イラストコンテストの締切が近づいてきたので慌てて Pixela でめそ子のイラストを描いたのでその技術的裏側について補足しておこうと思います。
ドット絵を描く
Pixelaは基本APIでpixelの値を入れる(色つけ)形なのでそのままではお絵かきには厳しいため、まずはドット絵用のツールでドット絵を描きます。 今回はPiskelを利用しました。はじめての利用だったけど使いやすかった!
最終的にはPixelaの色しか出せないので、Pixelaのグラフから各色を抜き出してカラーパレットに設定していきます。 色見本のブログがあったのでこれが大変役立ちました。
描いたドット絵はこちら
Pixelaは縦が7ピクセル、横が50ピクセルちょいなので、7*50で描きました。
www.piskelapp.com www.piskelapp.com
ドット絵のピクセルを読み込んでPixelaに値を登録する
JSで画像をCanvasに読み込んで、1ピクセルずつ読んで色からグラフのquantityに変換してPixelaにAPIで登録していきます。 開始点の日付から1日ずつPixelを読み進めていく感じです。 今回はajisaiとmomijiのカラースキームを使ったのでその対応表を仕込んでいますが、他の色の対応表を作ればその色でいけます。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>image2pixela</title> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script> <script type="text/javascript"> // PixelaのAPIキーを指定 const secret = 'thisissecret' // Pixelaのユーザ名を指定 const userName = 'username' const urlBase = `https://pixe.la/v1/users/${userName}/graphs/` // Pixelaに登録するグラフと画像のファイル名を一致させる const targets = ['akari-saiki', 'hisaki-hanasaki'] const colors = [{ // ajisai '-10': [71,141,141], '-6': [85,170,170], '-4': [141,199,199], '-1': [199,226,226], '0': [238,238,238], '1': [234,213,255], '4': [213,170,255], '6': [170,85,255], '10': [106,0,213], }, { // momiji '-10': [106,177,35], '-6': [128,213,43], '-4': [170,226,114], '-1': [213,241,184], '0': [238,238,238], '1': [255,213,213], '4': [255,128,128], '6': [255,43,43], '10': [255,0,0], }] window.onload = () => { for(let i = 0; i < targets.length; i++) { const canvas = document.getElementById(targets[i]) const ctx = canvas.getContext('2d') const img = new Image() // 他の画像形式の場合は拡張子調整してください img.src = `${targets[i]}.gif` img.onload = () => { ctx.drawImage(img, 0, 0) const data = ctx.getImageData(0, 0, canvas.width, canvas.height); const values = getValue(data, colors[i]) // 基準日の1年前の週の日曜日から描画スタート const baseDate = '2019-02-23' const endDate = moment(baseDate) const startDate = moment(baseDate) startDate.subtract(1, 'years') startDate.subtract(startDate.day(), 'days') values.forEach(value => { fetch( urlBase + targets[i] + `/${startDate.format('YYYYMMDD')}`, { 'mode': 'cors', 'method': 'PUT', 'headers': {'X-USER-TOKEN': secret}, 'body': JSON.stringify({'quantity': value}) } ).catch((error) => console.error(error)) console.log(startDate.format('YYYYMMDD') + ':' + value) startDate.add(1, 'days') }) } } } function getValue(data, colors) { const values = [] for(let i = 0; i < data.width; i++) { for(let j = 0; j < data.height; j++) { var idx = (i + j * data.width) * 4 Object.keys(colors).forEach(key => { const value = colors[key] if (data.data[idx] === value[0] && data.data[idx + 1] === value[1] && data.data[idx + 2] === value[2]) { values.push(key) } }) } } return values; } </script> </head> <body> <canvas id="akari-saiki" width="50" height="7"></canvas> <canvas id="hisaki-hanasaki" width="50" height="7"></canvas> </body> </html>
画像を読み込んでCanvasに叩き込むのにセキュリティ的な制限があるためローカルでは動作しないので、何かしらのWebサーバを立ち上げて動かす必要があります。 画像ファイルはHTMLと同じパスに置きます。 なお読み込んだだけでそのままPixelaのAPIを叩きに行くアグレッシブな仕様です。
できあがったものがこちらになります
みんなもPixelaでお絵かきしてみてくれよな!