3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Javascriptを使って、白背景の楽譜の背景を透明にする

Last updated at Posted at 2020-08-12

はじめに

ドラム譜を作成しようと思いMuseScoreというのを使って楽譜を作成したんですが、書いた楽譜のスクリーンショットを撮るとこんな感じになります

basic4beat.png

こういう白背景(厳密には真っ白ではないが)の楽譜の背景を透明にしたい場合、いろいろな方法があると思いますが今回はJavascriptを使って行ってみました。

最終的に背景を透明にした画像はこの様に重ねて使えるようになります。

スクリーンショット 2020-08-12 21.21.01.png

使うもの

  • mac
  • terminal
  • javascript
  • node.js
  • yarn
  • pngjs

上についてわからないものがあれば、Googleで調べてから再度ここにきてください。僕の過去の記事でも説明しているものがあると思うので参考にしてみてください。

書いたコード

const fs = require('fs')
const PNG = require('pngjs').PNG

fs.createReadStream('path/to/your.png')
    .pipe(new PNG())
    .on("parsed", function() {
        for (let y = 0; y < this.height; y++) {
            for (let x = 0; x < this.width; x++) {
                const index = (this.width * y + x) << 2;
                const r = this.data[index]
                const g = this.data[index + 1]
                const b = this.data[index + 2]
                if (r + g + b > 255 / 2 * 3) {
                    this.data[index + 3] = 0
                }
            }
        }

        this.pack().pipe(fs.createWriteStream('path/to/your/output.png'))
    })

解説

まずはpngjsのドキュメントを読みます。

最初からゴールが見えた様な状態のサンプルが書いてあったので、それを使いますが、前提知識として。

我々が普段使っているディスプレイは、1ピクセルという単位があり、1つのLEDのようなものです。例えばFullHDのディスプレイだと横に1920個・縦に1080個並んでいて、これらの色加減によって我々は画像を認識しています。

PNGの場合、1ピクセルは赤(red)・緑(green)・青(blue)・透明度(alpha)と言う4種類の単位で表現されます。rgbaとか言ったりしますね。

そして、データ上は先頭から[1ピクセル目のr][1ピクセル目のg][1ピクセル目のb][1ピクセル目のa][2ピクセル目のr][2ピクセル目のg]...という様に配列に格納されています。

それぞれ0~255までの256個の整数で構成されています。

ただこれだと全てのデータが横一列に並んでいるため、二次元の画像として使うためには高さ(width)と横幅(height)の情報が必要です。これもPNGファイルに含まれていて、その辺りはpngjsがうまいこと読み込んで処理してくれているのでこちらが考えることはrgbaデータをどの様に加工するかです。

ここまでが前提知識で、今回やりたかった白背景を透明にする部分ですが、途中にif (r + g + b > 255 / 2 * 3) {と書いた行があり、この条件式は白に近い色を判定するためのもので、この後の行this.data[index + 3] = 0の部分が透明にする処理です。

あとはサンプル通りですがファイルパスを正しく書き換えれば出力してくれます。

おわりに

正直このコード書くより記事書く方が1000倍大変です。。。

ちなみにですが、この条件式と背景処理だと、出力される画像が若干ジャギーになってしまいます(丸みを帯びた物(音符)を表現するために、丸い部分は曖昧な色が使われているため)。

なので、もっと滑らかに透明にしたい場合は条件式と後処理にもっと手を加える必要がありますね。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?