YUV⇒RGB変換

前回、AndroidでOpenGL ESを使用してYUVデータの表示を行いました。

今回はブラウザ上にYUV⇒RGB変換した画像を表示したいと思います。

現在、主要なブラウザでは、JavaScriptのAPIとしてOpenGL ESの派生規格であるWebGLをサポートしています。

今回、HTML5で追加された<canvas>要素に対し、ローカルファイルから読み込んだYUVデータをRGB変換して表示していきます。
最初は、YUV⇒RGB変換後の画像を2Dのレンダラーを使用して描画してみます。
その後、WebGLを使用した描画を行ってみます。
最後にWebGLとGLSL ESを使用し、GPUでYUV⇒RGB変換を行って画像を表示します。

なお、言語に関してはJavaScriptでも問題ないのですが、私としては型指定ができる方がしっくりと馴染むので、TypeScriptを用いたいと思います。

TypeScriptの開発環境

先ず、TypeScriptの開発環境を準備します。
詳細は他のホームページに任せますが、今回は以下の開発環境を使用します。

Visual Studio Code

IDE(開発環境)としてはVisual Studio Code(以下VSCode)を使用します。
こちらのページからダウンロードできます。

インストールについては

VSCode インストール

で検索すれば色々と出てきますのでそちらを参考にして下さい。

Live Server

現在のVSCodeでは、特に他のツール等を導入しなくても、単体でHTMLやJavaScriptの確認やデバッグを行うことができます。

一方、簡易なサーバーを立ち上げてHTMLやJavaScriptの確認やデバッグができれば、更に便利かと思います。
そんな場合に便利なのがVSCodeの拡張機能のLive Serverです。

使用方法等については、

Live Server

で検索すれば色々と出てきますのでそちらを参考にして下さい。

Node.js

TypeScriptのコンパイラー等の開発環境をVSCodeで使用する場合、Node.jsが必要となります。

WindowsではNode.jsのホームページから最新のインストーラーをダウンロードし、実行するだけでインストールできます。

その他のプラットホームでのインストールはNode.jsのダウンロードページにリンクがありますので、参照して下さい。

プロジェクト作成

開発環境が整いましたら、プロジェクトを作成して行きます。
今回はNode.jsを使用してプロジェクトを構築します。

先ず、プロジェクトを作成したいフォルダーを適当に作成して下さい。
例えば”ShowYUVwithWebGL”と云うフォルダーを作成し、プロジェクトのフォルダーとします。

VSCodeをオープンします。
“ファイル”メニューから”フォルダーを開く…“を選択し、作成したプロジェクトのフォルダーを選択します。
VSCodeの新しいウィンドウがオープンします。

TypeScriptのコンパイラーのインストール

TypeScriptのコンパイラーのインストールの方法は色々とあるようですが、今回はNode.jsの”npm”コマンドでインストールします。

VSCodeで”Ctrl-@“等でターミナルをオープンします。
ターミナルで以下のコマンドによりTypeScriptのコンパイラーをインストールします。

npm install -g typescript@latest

なお、“-g”オプションは、グローバルにインストールすることを示し、他のプロジェクトでもTypeScriptのコンパイラーを使用できるようにします。
“-g”オプションを使用しない場合は今回のプロジェクトでのみTypeScriptのコンパイラーを使用できるようになります。

TypeScriptのバージョン確認

以下のコマンドでTypeScriptのバージョンを確認できます。

tsc -v
    

もしバージョンが想定しているより低い、例えば”1.0.0”等のような場合には、デフォルトで古いバージョンのTypeScriptがインストールされている可能性があります。
環境変数の”Path”に”C:Files (x86)SDKs\1.0.x.x”等が記載されていないか確認して下さい。
もし記載がある場合には”Path”から削除してみて下さい。

tsconfig.jsonの作成と修正

以下のコマンドによりTypeScriptのコンパイルのデフォルトの設定ファイル”tsconfig.json”が作成されます。

tsc --init

デフォルトの設定ファイルに対しては、以下の修正、追加を行います。

targetを変更

“target”の項目を”ES6”に変更します。

"target": "ES6",
      
moduleを変更

“module”の項目を”commonjs”から”ES2015”に変更します。

"module": "ES2015",
ベースURL指定

インポート文で絶対パス指定をできるようにベースディレクトリを指定します。

"baseUrl": "./src",
        
入力及び出力ディレクトリの追加

ソース元のディレクトリとコンパイル後のファイルを出力するディレクトリを追加します。
以下の項目の行のコメントアウトを外し、値を修正します。
なお、ディレクトリ名は適宜変更してもOKです。

"rootDir": "./src",
"outDir": "./dst/js",
        

更に、此処で指定したディレクトリに対応したフォルダをプロジェクトフォルダ”ShowYUVwithWebGL”下に作成しておきます。

階層化したコンパイル対象の指定

階層化したファルダをコンパイルの対象とするため、“include”の項目を以下のように追加します。

"compilerOptions": {
    :
    :
  },
"include": ["src/**/*"]
        
JavaScriptを対象

念のため、JavaScriptファイルを対象とするように以下の項目のコメントアウトを外しておきます。

"allowJs": true,
sourceMapの追加

デバッグ用のソースマップを作成するため以下の項目のコメントアウトを外しておきます。
リリースする際には再度コメントアウトしてソースマップを作成しない様にします。

"sourceMap": true,
        

プロジェクトの初期化

“Ctrl-@”等でオープンしたターミナルで以下のコマンドを実行し、プロジェクトを初期化します。

npm init -y

作成された”package.json”については、以下のように修正を行います。

スクリプト修正

“package.json”の”scripts”の値を以下のように修正し、次に導入するwebpackのコマンドをNPMスクリプトとして登録します。

"scripts": {
  "build": "webpack",
  "build:watch": "webpack -w",
  "node_modules": "npm ci"
},
    

なお”package-lock.json”に従ってnode_modules内のパッケージを再インストールするためのコマンドも追加しています。

webpackの導入

今回、TypeScriptのコードを書くのですが、クラス毎にファイルを分割したいと思います。
ただ、コンパイル後に作成される、複数のJavaScriptのファイルをHTMLで読み込み、動作させるには、色々と面倒な手続きがあり、容易ではありません。

webpackは、TypeScriptのファイルから作成された、分割されているJavaScriptのファイルを1つに纏め、HTMLから読み込めるようにしてくれるツールです。
他にも機能はあるのですが、詳細は他のホームページに任せます。

インストールは”Ctrl-@“等でオープンしたターミナル上で以下のコマンドを使用します。

npm install --save-dev webpack webpack-cli ts-loader

webpack.config.jsの作成

以下の内容でwebpackの設定ファイル”webpack.config.js”を作成します。

const path = require('path');
module.exports = {
    mode: 'development',
    entry: {
        index: './src/index.ts',
    },
    output: {
      path: path.join(__dirname, 'dst/js'),
      filename: 'index.js',
    },
    resolve: {
      extensions: ['.ts', '.js'],
    },
    devServer: {
        static: {
            directory: path.join(__dirname, 'dst'),
        },
        open: true,
    },
    module: {
        rules: [
            {
            test: /\.ts$/,
            loader: 'ts-loader',
            },
        ],
    },
    target: 'electron-main',
};