今週はじめに私は私が今年初めに書いたFirefox 付加の呼ばれたWIPS に携帯用ピクセル地図(PPM)のフォーマットの セービングの イメージのためのサポートを加えた。 なぜ頼むかもしれないPPMサポートを加えることを迷惑を掛けなさいか。 それで、PPMのフォーマットはおそらくUnixおよびGNU/Linuxのプラットホームの共通の使用にあるイメージ交換フォーマットの中の小さい共通分母の1つである。
私はJavaScriptにFirefoxが支えたすべてのプラットホームを渡って携帯用であるのはPPMのイメージのserializerを書いたからである。 私は共有ライブラリかDDLに出動したかもしれない例えば netpbmの`sのlibnetpbmは、それは私が共有ライブラリがあるように確認し、次に共有ライブラリが利用できない場合を扱うように要求したが。
形式化された指定がない、IECまたはIEEEのようなSDOによって開発されるすなわち指定なぜならPPMのイメージのフォーマットしかし事実上の指定はSourceForgeで見つける ことができる。
HTML5キャンバスのための源はPPMのserializerにここにある:
createPPM : function(canvas, destFile, usegamma)
{
const MAXVAL = 255;
var width = canvas.width;
var height = canvas.height;
var ctx = canvas.getContext("2d");
var canvasData = ctx.getImageData(0, 0, width, height);
// build the Bt.709 gamma tables
if (this.ppmgamma) {
var rGammaTable = new Array(MAXVAL + 1);
var gGammaTable = new Array(MAXVAL + 1);
var bGammaTable = new Array(MAXVAL + 1);
this.buildBT709GammaTable(rGammaTable, MAXVAL);
this.buildBT709GammaTable(gGammaTable, MAXVAL);
this.buildBT709GammaTable(bGammaTable, MAXVAL);
}
// build file header
var fileHeader = "P6\n";
if (usegamma) {
fileHeader += "# BT.709 gamma adjustment applied\n";
} else {
fileHeader += "# No gamma adjustment applied\n";
}
fileHeader += width + " " + height + "\n";
fileHeader += MAXVAL + "\n";
// build data
var imgData = canvasData.data;
var pixelData = [];
for (var i = 0, n = imgData.length; i < n; i += 4) {
pixelData.push(imgData[i]); // red
pixelData.push(imgData[i+1]); // green
pixelData.push(imgData[i+2]); // blue
// skip alpha channel
}
// now fix up gamma values
if (usegamma) {
for (var i = 0; i < pixelData.length; i += 3) {
pixelData[i] = rGammaTable[pixelData[i]];
pixelData[i+1] = gGammaTable[pixelData[i+1]];
pixelData[i+2] = bGammaTable[pixelData[i+2]];
}
}
var file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(destFile);
if (file.exists()) {
file.remove(true);
}
file.create(file.NORMAL_FILE_TYPE, 0666);
var fileStream = Components.classes['@mozilla.org/network/file-output-stream;1']
.createInstance(Components.interfaces.nsIFileOutputStream);
fileStream.init(file, 2, 0x200, false);
var binaryStream = Components.classes['@mozilla.org/binaryoutputstream;1']
.createInstance(Components.interfaces.nsIBinaryOutputStream);
binaryStream.setOutputStream(fileStream);
binaryStream.write(fileHeader, fileHeader.length);
binaryStream.writeByteArray(pixelData, pixelData.length);
binaryStream.close();
fileStream.close();
},
//
// Note - formulas come from netpbm package
//
buildBT709GammaTable : function(table, maxval)
{
var i = 0;
var gamma = 1/0.45; // Per ITU BT.709
var oneOverGamma = 1/gamma;
var linearCutoff = maxval * 0.018 + 0.5;
var linearExpansion = (1.099 * Math.pow(0.018, oneOverGamma) - 0.099) / 0.018;
for (i = 0; i <= linearCutoff; ++i) {
table[i] = i * linearExpansion;
}
for (; i <= maxval; ++i) {
var normalized = i / maxval;
var v = 1.099 * Math.pow(normalized, oneOverGamma) - 0.099;
table[i] = Math.min((v * maxval + 0.5), maxval);
}
}
createPPM機能は3つの議論を期待する: イメージが 貯えられるべきであるところHTML5キャンバスの要素、ファイル名およびガンマの調節は要求されるかどうか示すブール。 私はキャンバスの要素をよく知られていると仮定しようと思っている; XULの内のからのそれを使用する方法をない Mozillaに それのよい個人指導がおよびあれば 。
機能はPPMの場合には最初にファイル見出し(fileHeader) -である非常に簡単造る。 ファイル見出しのための指定はここにある:
- ファイル・タイプを識別するマジックナンバー。 マジックナンバーはPPMのための2つの特性P6である。
- 1つ以上whitespace (ブランク、タブ、改行、CR、LF)。 私は改行を使用するために選ぶ
- ASCIIの小数としてフォーマットされていたイメージの幅はASCIIの小数としてフォーマットされていたイメージの高さに先行しているwhitespaceによって続いた。 私は幅と高さの間にブランクを置くことを選ぶ。
- 1つ以上のwhitespaces。 私は改行を使用するために選ぶ。
- ASCIIの小数としてフォーマットされている最高色の価値(maxval)。 65536よりより少しはあるなるおよび以上ゼロ。
- 単一のwhitespaceの特性。 私は改行を使用するために選ぶ。
ファイル見出しは順序で高さの列のベクトルに、完全に先行している。 各列は順序で幅ピクセルから、左から右へ成っている。 各ピクセルはその順序で赤く、緑、および青のサンプルの三重項、である。 αチャネルのためのサポートがない。 各サンプルは1か2バイトにつき純粋なバイナリで表される。 maxval 256のそれが1バイトであるよりより少しはである; 最初に最上位のバイトのさもなければ2バイト。 maxval上記のコードの場合には定数、価値が255のMAXVALはある。 それ故にピクセルサンプルはたった1バイトである。
PPMの指定はファイルのサンプル価値がイメージの特定の輝度を表すことを指定する従って-サンプルのガンマの調節は要求される。 特に、彼らはサンプル価値がITU-Rの推薦BT.709によって定義されるように光に正比例していることを 指定する。 ここに光輝の機能として光は黒の近くで線形傾斜路と変更される力機能である。 私達の場合255,255,255のすべての3つの部品のためのmaxvalの価値は、すなわち、白い 色の 宇宙(このイメージが部分であるこのイメージが比較されるかもしれないすべてののCIE D65および最も強い色をイメージのすべての色表す)。 上で示されているbuildBT709GammaTable機能はBT709ガンマの調節の参照用テーブルを造る。
ガンマものについて混同されるか。 簡潔な説明は助けるかもしれない。 コンピュータで使用のためにイメージをコードする単純な方法の1つは、例えばちょうどコードするピクセルの赤く、緑および青の部品をピクセルの色の部品の光輝に正比例しているサンプル価値を使用することである。 光輝は ライトの電力量に基づく物理的な測定である。 但し光輝は人間の目がそれと同様、できる高光輝色間の相違低光輝色間の相違を検知できないのでライトが人へのように見えるもの考慮に入れない。 相違を補うためには、ガンマの伝達関数は使用される。
変形プロセスはガンマの調節呼ばれる。 主観的な明るさに比例したガンマ調節された価値はピクセルの光 として 知られている。 結果はサンプルの変更により同レベルのサンプル範囲の感知された色の変更をどこでも引き起こすべきであることである。 光輝とは違って、明るさの認識がいろいろな要因に従って変わるのでイメージが見られる環境を含む光を、測定する精密で客観的な方法がない。 これらの理由により、ちょうど1つのガンマの伝達関数がない。
事実上すべてのイメージのフォーマットは、PPMを含んでサンプル価値のために、使用価値をガンマ調節した。 この主題についての詳細を学びたいと思えばよい開始の場所はチャールズPoyntonガンマ FAQである。 もう一つの適切な場所はガンマの訂正のWikipediaの 記事である。
PPMのイメージのための共通の変化は光輝(AKAの線形強度)に正比例しているサンプル価値を使用することである。 これはガンマの調節を意味しない。 これは、WIPSで、実際に好みの設定であるブールusegammaによってcreatePPMで支えられる。 netpbmのpnmgammaのような独立型ユーティリティーがガンマ調節されたPPMに線形PPMを変えるのに使用することができる。
PPMのイメージのためのもう一つの共通の変化はサンプルをIEC (国際電気標準会議)のsRGBの標準 によって 定義されるように光に比例したように すること である。 sRGBのガンマの伝達関数はBT.709ガンマの伝達関数と同一である但し例外としては異なった定数を使用する。
sRGBは平均オフィスのPCのスクリーンを模倣するように意図されている色スペースである。 すべてのPCが同一ではないし、従って共通色スペースを持っていない。 sRGBは平均場合の近似単にである。 Apple MacはsRGB色スペースに合致するために形成することができるが、デフォルトでconformantではない。 CSS2 指定 および草案 CSS3の指定CSS 色に従って価値はsRGB色スペースを示す。
sRGBのガンマの調節の参照用テーブルを造るJavaScript機能はここにある:
//
// Note -formulas come from netpbm package
//
buildSRGBGammaTable : function(table, maxval)
{
var i = 0;
var gamma = 2.4; // per IEC sRGB
var oneOverGamma = 1/gamma;
var linearCutoff = maxval * 0.0031208 + 0.5;
var linearExpansion = (1.055 * Math.pow(0.0031308, oneOverGamma) - 0.055) / 0.031308;
for (i = 0; i <= linearCutoff; ++i) {
table[i] = i * linearExpansion + 0.5;
}
for (; i <= maxval; ++i) {
var normalized = i / maxval;
var v = 1.055 * Math.pow(normalized, oneOverGamma) - 0.055;
table[i] = Math.min((v * maxval + 0.5), maxval);
}
}
このポストのJavaScriptのソースコードは自ら明らかなべきである。 私はそれを詳しく説明することの価値を見ない。 私はWIPSで目的を指定するのにJavaScript prototypalパターンを使用した。 自明もし標準的なJavaScript機能に例コードを変える方法。 あなたのプロジェクトの何れかでコードを使用すること私にそれを帰因する提供したことを自由ことを感じなさい。
楽しみなさい!


























