JavaScript画像処理周りスニペット(Canvas, Image)

ファイルから画像を読み込んで、Canvasへ描き込んで、Canvasの画像を加工して、Canvasから画像ファイルをダウンロードってことをやる。



See the Pen
Image processing
by ninomae-makoto (@ninomae-makoto)
on CodePen.





ファイルから画像書き込み



// ファイル読み込み
function onFileChanged() {
  
  const file = event.target.files[0]

  // ファイル読み込み
  // readerのresultプロパティに、データURLとしてエンコードされたファイルデータを格納
  const reader = new FileReader()
  reader.readAsDataURL(file)

  reader.onload = () => {
    image.onload = (ev) => {
      drawImage()
    }
    // canvasに書き込み
    if (reader.result) {
      var result = reader.result
      image.src = result
    }
  }
}


少し分かりづらいが20行目のimage.src = resultで画像を読み込み始める。
画像の読み込みが完了したらimage.onloadの処理が呼ばれる。



Canvasへ描き込み


// 塗りつぶし
function fillRect() {
  
  var canvas = document.getElementById("canvas") 
  var ctx = canvas.getContext("2d")
  ctx.fillStyle = "gray"
  ctx.fillRect(0, 0, canvasWidth, canvasHeight)
}

// テキストの描画
function drawText() {
  var canvas = document.getElementById("canvas") 
  var ctx = canvas.getContext("2d")
  ctx.font = "16px serif"
  ctx.fillStyle = "black"
  ctx.fillText("Hello canvas", 10, 50)
}

// 読み込んだ画像を表示する
function drawImage() {
  const canvas = document.getElementById("canvas")
  // キャンバスに画像描画
  const ctx = canvas.getContext("2d")
  ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight)
}

コンテキストを取得してフォントや塗りつぶしスタイルなどを設定したあと描画処理を呼び出すが基本の流れ。



Canvasから画像ファイルをダウンロード



function downloadImage() {
  var canvas = document.getElementById("canvas") 
  var data = canvas.toDataURL("image/jpeg")
  // console.log(data)
  const fileName = "test.jpeg"

  // ダウンロード処理
  if (window.navigator.msSaveBlob) {
    // IE, Edge
    var blob = new Blob([data], { type: "application/x-msdownload" })
    window.navigator.msSaveOrOpenBlob(blob, fileName)
  }
  else {
    // Chrome, FireFox
    var link = document.createElement("a")
    link.setAttribute("download", fileName)
    link.href = data
    // link.href = URL.createObjectURL(blob)
    var evt = document.createEvent("MouseEvents")
    evt.initEvent("click", false, true)
    link.dispatchEvent(evt)
  }
}


ブラウザによって微妙に処理が違う。
詳細は以下にまとめている。
https://trueman-developer.blogspot.com/2016/05/javascript_8.html



画像のフォーマットについて



canvas.toDataURLで取得した値は先頭に文字列が付与されるのでJavaScript外に持ってくるとそのままでは使いづらい。
data:image/jpeg;base64,xxxxxxxxxxxx...
以下のようなスニペットが使える。

var canvas = document.getElementById("canvas")
var imgURL = canvas.toDataURL("image/jpeg")
var imgData = imgURL.slice(imgURL.search("base64,") + 7)



参考



https://developer.mozilla.org/ja/docs/Web/API/Canvas_API
https://developer.mozilla.org/ja/docs/Code_snippets/Canvas

2019年6月25日火曜日