▼レイヤーブレンドモードの作り方

ネコペのレイヤーモードは増やす事が出来ます
ネコペをインストールしたフォルダ\plugin\blend
に.dllファイルを入れるとレイヤーブレンドモードが増えます

作る為の見本として同じフォルダにblend1.cppとblend1.defというファイルが入っています
これは差の絶対値として書かれたブレンドモードのソースです
この二つのファイルと同じようにソースを書いて、
それをどうにかして.dll形式に変換してやればネコペでも読み込めるようになります



dllへの変換が出来たので忘れないうちにメモ


●ネコペで使える形に書き出す方法(.dllへの変換)
blend1.cppとblend1.defを.dll形式に変換してみたいと思います
まず、.cppとはC++で作られるファイルです。
なのでC++用のプログラミングソフトを導入する事にしました
他にコンパイル(変換)できるソフトであればなんでも良いです
(というかMicrosoft Visual C++ 2008 Express Editionでの方法しか理解できてない)

Microsoft Visual C++ 2008 Express Edition
という無料のプログラミングソフトをインストールしました
(今は2010と2012のバージョンが配布されてます
Microsoft Visual C++ Express Editionで検索してみてください。Express Editionというのが無料のものです
ユーザー登録すれば無期限で無料で使えます)


Microsoft Visual C++ 2008 Express Editionを起動します
[ファイル]→[新規作成]→[プロジェクト]で新規作成
するとダイアログ画面が出てくるので
[Win32]→[Win32コンソールアプリケーション] を選び、プロジェクト名を適当に付けて「OK」を押す


Win32アプリケーション ウィザードが出てくるので「次へ」をクリック
[アプリケーションの種類]という項目で[DLL]を選び、「完了」をクリック
([空のプロジェクト]にはチェックを入れないで下さい)



すると、ソースファイルにdllmain.cpp、stdafx.cpp、プロジェクト名.cpp、
ヘッダーファイルにstdafx.h、targetver.hが入ったプロジェクトが作成されます


本来ならdllmain.cppにブレンドモードのソースを書くのではないかと予想してますが(あまり理解していない)
今回は作者さんが作った見本のソースを.dll形式にしたいのでdllmain.cpp、プロジェクト名.cppを削除します
それぞれ左に表示されてるファイル名を右クリックして削除


では、見本のblend1.cppとblend1.defを追加したいと思います
まずプロジェクトが保存されているフォルダをエクスプローラーで開きます
My Documents\Visual Studio 2008\Projects\プロジェクト名\プロジェクト名  です(OSによって違うかも?)
(先ほど残しておいたstdafx.h、targetver.h、stdafx.cppがあるフォルダです)
そこに、ネコペをインストールしたフォルダ\plugin\blend にあるblend1.cppとblend1.defを追加してください


Microsoft Visual C++ 2008 Express Editionに戻ります
My Documents\Visual Studio 2008\Projects\プロジェクト名\プロジェクト名
にあるblend1.cppとblend1.defを
[プロジェクト]→[既存の項目の追加]で追加します
左側のソースファイルという項目に追加されていればOKです


次に、左側に表示されているプロジェクト名を右クリックし、[プロパティ]を開きます


[構成プロパティ]→[リンカ]→[入力]で「モジュール定義ファイル」の項目に「blend1.def」と書く


更に[構成のプロパティ]→[C/C++]→[コード生成]で「ランタイムライブラリ」の項目で「マルチスレッド(/MT)」を選択し、「OK」を押す
(このランタイムライブラリの項目を設定しておかないと、配布した時に環境依存で使えない人が出てきます)



設定はここまでです。ではいよいよ.dllに書き出します
[ビルド]→[ソリューションのビルド]を押すと書き出しが始まります
画面下に結果が表示されるので「1 正常終了」と書かれていれば書き出し成功です
(修正しつつ何度も保存しなおす時は[ビルド]→[ソリューションのリビルド]のほうが確実かも。)

dllファイルは
My Documents\Visual Studio 2008\Projects\プロジェクト名\Debug
に書き出されます


書き出されたdllを
ネコペをインストールしたフォルダ\plugin\blend
に入れて、ネコペを起動してみてください。レイヤーブレンドモードに追加されているはずです


やり方があっているのかは分かりませんが
とりあえず出来たという方法でした

おわり




--------------------


・間違えてstdafx.cppを消した場合の追加方法
[プロジェクト]→[新しい項目の追加]で、[コード]→[C++ファイル(.cpp)]を選択し、
ファイル名を「stdafx.cpp」にして「追加」をクリック
そのファイル内に「#include "stdafx.h"」と一行だけ書く
左側に表示されているstdafx.cppを右クリックし、「プロパティ」を開く
[構成プロパティ]→[C/C++]→[プリコンパイル済みヘッダー]で 「プリコンパイル済みヘッダーの作成/使用」の項目を「プリコンパイル済みヘッダーを作成する(/Yc)」に変更する
これを設定しておかないとエラーが起こります







▼ソースの内容

プログラム初心者なので自分で理解できた事だけをまとめてみました
間違ってる可能性もありますので注意

blend1.cppとblend1.defはメモ帳などのテキストエディタで開く事が出来るので
そちらと見比べながら読んでください



●.defファイル関連
LIBRARY "blend1"

EXPORTS
get_blend_func_count @1
get_blend_func_key @2
get_blend_func_name @3
blend @4
merge @5


LIBRARY
dll名を設定。最終的に書き出される.dllの名前と一致していないとエラーが出るかも?

EXPORTS
この部分は基本的にいじらなくても大丈夫だと思います
関数名と序数を指定。
get_blend_func_countという関数がget_blend_func_countという名前でdllファイルに定義される。
序数値は「@」の後ろに書かれた番号になる。
dllファイルは、関数を序数と呼ばれる値で保持しているらしい




●.cppファイル関連
__stdcall
は、呼び出す側が、VB.NET 等のVC++以外の言語でも対応が可能な規約を指す
これに対して、__cdecl は、C/C++ のみ限定の規約


char  の値は -128〜127 まで
unsigned char  の値は 0〜255 まで

const装飾子
constが付いている変数は変更出来ない。元のままの値が変更されない


//psdファイルに保存するときのkeyを返す。
'norm' = normal(通常)
'dark' = darken (比較(暗))
'lite' = lighten(比較(明))
'hue ' = hue(色相)
'sat ' = saturation(彩度)
'colr' = color(カラー)
'lum ' = luminosity(輝度)
'mul ' = multiply(乗算)
'scrn' = screen(スクリーン)
'diss' = dissolve(ディザ合成)
'over' = overlay(オーバーレイ)
'hLit' = hard light(ハードライト)
'sLit' = soft light(ソフトライト)
'diff' = difference(差の絶対値)
'smud' = exlusion(除外)
'div ' = color dodge(覆い焼きカラー)
'idiv' = color burn(焼き込みカラー)

このキーは4文字まで。
文字数がオーバーするとpsdで保存して開きなおした時に
レイヤーモードが「?」で表示され、いちいち選びなおさなくてはいけなくなる
上に書いたレイヤーモードの和訳は勝手に追加しましたが、
photoshop標準の名前なのでネコペにはないレイヤーモードもある

ちなみにネコペのレイヤーモードでは↓でした(最後の空白スペースも含みます)
'norm'  通常
'mul '  乗算
'scrn'  スクリーン
'lddg'  加算
'diff'  差の絶対値

'pass'  通過  ※フォルダのみにあるモード


有志による追加分↓
'sub '  減算
'dark'  比較(暗さ)
'lite'  比較(明るさ)
'over'  オーバーレイ
'hLit'  ハードライト
'sLit'  ソフトライト
'div '  覆い焼き
'idiv'  焼き込み
'hue '  HSV合成(色相)
'sat '  HSV合成(彩度)
'col '  HSV合成(カラー)  ※フォトショの「カラー」とは別物なのでキーの名前が違うっぽい
'val '  HSV合成(明度)
'red '  RGB合成(赤)
'gren'  RGB合成(緑)
'blue'  RGB合成(青)  ※保存して開きなおすと「?」になるので.dll側で5文字オーバーなのかも(psd内では'blue'で保存されてました)
                ※dll内で確認した所「bluet」になっていました。文字数オーバー
'or'   論理和  ※4文字じゃなく2文字になってる?
'and '  論理積
'xor '  排他的論理和
'not '  否定
'imp '  論理包含
'mono'  2値化
'mul2'  乗算(不具合回避用)

'vLit'  ビビットライト
'lLit'  リニアライト
'pLit'  ピンライト
'sand'  砂トーン
'san2'  砂トーン(2dot)
'sabw'  砂トーン(黒白)
's2bw'  砂トーン(2dot黒白)
'dot'   600dpi 50線   ※4文字じゃなく3文字
'dotw'  600dpi 50線 黒白
'hueh'  色相変更スライダー
'smud'  除外

'cClr'  Cカラー
'rlct'  反射
'glow'  グロー

'niti'  二値化(修正版)
'gray'  グレースケール化



------------------------------------


差の絶対値の色の計算方法は

  (結果の色) = (下に表示されてる色)−(現在のレイヤーの色) の絶対値

になります。絶対値とは−3が出た時はマイナスを取って3になるような値です
どれだけ差があるかを計るものなのでマイナス値は出ません
絶対値なので(下に表示されてる色)と(現在のレイヤーの色)が逆になっても数値は変わりません
また、全く同じ画像(不透明度100%)を重ねた場合、同じ数字から同じ数字を引くので必ず数値は0になります
RGB=(0,0,0)になるので真っ黒で表示されます

この計算式に透明度を計算に加えたのが実際に画面に表示される色となります





abs()
が絶対値の数値に直してくれる命令(関数)
負なら正、正なら正の数値にしてくれます


*dst
*(dst + 1)
*(dst + 2)
が最終的に表示されるRGB値です(上から順番にB、G、R)
更に、この式の中に入ってる*dst、*(dst + 1)、*(dst + 2)(全く同じ名前)が元々表示されていた下のRGB。(下のレイヤーではなく、下にある全てのレイヤーのRGB)
元々表示されていた色を使って新しい色に書き換えている。
dstって表示されてるもの、みたいな意味合い?

//合成を行う関数
の部分では画面に表示される色を決める。
グレーモードの時は*dstのみ(色情報のグレースケールのみ)
カラーモードの時は*dst、*(dst + 1)、*(dst + 2)の三つのみ(RGB値のみ)
最終的に”画面に表示する為の色”を指す
α値を設定する項目が無いので、色の式の中にα値も取り入れた結果の色を表現しなくてはならない

//下のレイヤーと結合
はその名の通り、「下のレイヤーと結合」をするときに使う計算式
*dst〜の数が一個増えて、それぞれα値情報が設定できる
グレーモードの時は*dstが色合い(グレースケール)で、*(dst + 1)がα値
カラーモードの時は*dst、*(dst + 1)、*(dst + 2)がそれぞれRGB値で、*(dst + 3)がα値
最終的に ”レイヤー情報として書き込まれる” RGB+α値(グレースケール+α値)を指す


*col
if (num_channel == 1) のグレースケールモードの時は
現在のレイヤー上にある色情報(グレースケール)の数値を表す
if (num_channel == 3) のカラーモードの時は
現在のレイヤー上にあるRGB値のBの数値を表す

*col
*(col + 1)
*(col + 2)
が現在のレイヤーのRGB値です(if (num_channel == 3) のカラーモードの時)
上から順番にB、G、R

*alpha
が現在のレイヤーの透明度情報(α値+レイヤー不透明度スライダの値も入っている)

*base_col
*(base_col + 1)
*(base_col + 2)
//下のレイヤーと結合 の式の中にあるので、
ひとつ下にあるレイヤーのRGB値
上から順にB、G、R

*base_alpha
//下のレイヤーと結合 の式の中にあるので、
一個下にあるレイヤーのα値

//num_channel チャンネル数。グレーモードの場合は1、カラーモードの場合は3
グレーモードはグレ猫を使った時用で、ネコペはカラーモードしか使ってないはず

if (no == 0) {//差の絶対値
noというのは、ひとつの.dllファイルの中で何番目にあるブレンドモードなのかを指す(0から数える)
ひとつの.dllの中に複数のブレンドモードを作れます



const unsigned char* col_end = col + num_pixel * col_step;
while (col < col_end) {
(略)
alpha += alpha_step;
col += col_step;
dst += col_step;
}
これはそういう物として必ず書いてください
(略)の部分に色の計算式を書いてください

これは画面をブロック状に切って小分けに表示する為の式だと思います
一回ずつキャンバス全体の表示を更新するのでは処理が遅くなるので軽くするための処置ですね
私も細かい部分はよく分かっていません
.dll側でいじっても画面に表示できなくなるだけなので下手にいじらないほうが良い
//下のレイヤーと結合 の式では微妙に違う部分(dst += 2;になってたり)があるので要注意

  <予想>
  キャンバス、色情報、α値の三つの情報があって
  num_pixelはキャンバスでのxy座標をナンバリングしたもの、
  colは色情報でのxy座標をナンバリングしたもの、
  alphaはα値でのxy座標をナンバリングしたものではないかな?
  colからcol_endまでのxy座標の色を書き換える?
  alpha_step、col_stepは次の座標へ行くための数値とか。


*マーク
掛け算として使われる*ではなく、
*alphaみたいに変数の前についてる*マークはポインタ(アドレス情報)を指す
私もあまり理解できていません
ネコペと.dll側で色や透明度の数値を共有できるようにしてるのではないでしょうか


式内での数値
RGB値は0〜255
α値(不透明度)も0〜255で扱われている
色の計算式をネットなどで調べると、α値が0.0〜1.0で扱われている場合が多いので
式内で 1 = 255 、0.5 = 127 になるような式に変更する必要があります


(unsigned char)(int)
計算式の中に入っている型名はキャストと呼ばれる
小数点以下が扱えない型で計算していると計算結果が狂う時があります(計算結果1.5が1になったり)
それを強制的に他の型で計算させて正確な数値を得たりするのがキャストです






私が作った「二値化(修正版)」「グレースケール化」のソース(.cpp)の内容を置いておきます
.dllはこちらでダウンロードできます→<download>






<HOME>