まよねーず工場

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--/--/-- --:-- |スポンサー広告  

Unityを使ったパレット変換

現在仕事でUnityを使用しております。
画像の色違いを扱うときに色別に画像データを持つといろいろとメモリがやばくなるので
プログラム内で直接テクスチャの色をつけて生成することにしました。


GUI.Textureには
GetPixel
SetPixel
Apply
LoadImage
EncodeToPNG
といったメソッドが存在し
width
height
というプロパティが存在します。

GetPixel( x , y )でテクスチャ内のピクセルの座標(0,0なら一番左端)を指定し、
そこからカラーを持ってきます。
そしてそこのカラーに新しいカラーを入れて
SetPixel( x , y , color )にカラーのセット

最後にApply()メソッドを呼ぶことで色の変更は終了


といった感じになります。




///


/// 画像カラー情報クラス
/// どこの座標の色は何色か?という情報を持つ
///

class GraphicColor{
public int x;
public int y;
public Color color; //変換するカラー


public GraphicColor( int _x , int _y , Color _color )
{
set( _x , _y , _color );
}

public GraphicColor()
{
x = 0;
y = 0;
color = new Color();
}

public void set( int _x , int _y , Color _color )
{
x = _x;
y = _y;
color = _color;
}
}




///
/// 色彩変換を行う
///

///
public static Texture2D palletConvert( AlphaChannel alpha , Color blendColor , Texture2D texture )
{
Texture2D result = texture;
for( int i = 0 ; i < alpha.Length ; i++ ){
Color c = new Color();
c.r = alpha[i].color.r;
c.g = alpha[i].color.g;
c.b = alpha[i].color.b;
c.a = alpha[i].color.a;

c = colorBlending( blendColor.r , blendColor.g , blendColor.b , c );
result.SetPixel( alpha[i].x , alpha[i].y , c );
}

result.Apply();
return result;
}




今回はレイヤーマスクのようなものを先に読み込み、
白黒のグラデーションからパレット変換の範囲を指定するというプログラムを作る必要があったので
以下のようなクラスを作成




///
/// アルファチャンネルクラス
///

class AlphaChannel{
private Texture2D alphaChannel;
private List enableArea; //アルファ範囲

public GraphicColor this[int index]{
get{
return enableArea[index];
}
}

public int Length{
get{
return enableArea.Count;
}
}

public Texture2D getAlphaChannel{
get{
return alphaChannel;
}
}

///
/// アルファチャンネル画像を取り込む
///

///
public AlphaChannel( string fileName )
{
enableArea = new List();
alphaChannel = (Texture2D)Resources.Load( fileName );
ImportAlphaChannel();
}

///
/// チャンネル範囲を調べる
/// カラーの付いた部分はチャンネル範囲、
/// 真っ白、アルファ値ゼロは評価範囲には含まれない
///

public void ImportAlphaChannel()
{
for( int y = 0 ; y < alphaChannel.height ; y++ ){
for( int x = 0 ; x < alphaChannel.width ; x++ ){
Color pixelColor = alphaChannel.GetPixel( x , y );
Color c = new Color();
c.r = pixelColor.r;
c.g = pixelColor.g;
c.b = pixelColor.b;
c.a = pixelColor.a;

//アルファ値0とホワイトカラーはノーカウント
if( c.a == 0.0f ){
continue;
}
if( c.r == 1.0f && c.g == 1.0f && c.b == 1.0f ){
continue;
}

enableArea.Add( new GraphicColor( x , y , c ) );
}
}
}

public AlphaChannel()
{
alphaChannel = null;
enableArea = new List();
}
}




なるべく原色ベースに色変換するほうが綺麗に塗り変わるので
フォトショでいうところの色彩変換を行います。
///
/// 原色を維持しながら加算成分をブレンドします
/// 引数で渡された色 / 最大値から出された割合 * 加算成分で計算して色彩を変える
///

/// 加算成分r
/// 加算成分g
/// 加算成分b
/// 変更したいカラー
///
public static Color colorBlending( float r , float g , float b , Color color )
{
Color result = new Color();
result.r = color.r;
result.g = color.g;
result.b = color.b;
result.a = color.a;
result.r += ( color.r / 1.0f ) * r;
result.g += ( color.g / 1.0f ) * g;
result.b += ( color.b / 1.0f ) * b;

return result;
}




なお、GetPixelとSetPixelで変換したテクスチャは元に戻りません。
Project内にあるテクスチャはプログラムを終了しても塗り変わったままなので、

プログラム内で独自にリソースから持ってきたテクスチャをベースに新しいテクスチャを作成する必要があります。



///
/// テクスチャを生成する
/// Project内の画像を直接色彩変換すると元に戻らないので
/// 必ずこのクラスで生成したテクスチャを使うこと。
///

///
///
public static Texture2D BuildingTexture( Texture2D texture )
{
Texture2D result = new Texture2D( texture.width , texture.height );
byte[] texbyte = texture.EncodeToPNG();

result.LoadImage( texbyte );
return result;
}





こんな感じのプログラムにより、無事色彩変換に成功。
といった感じで今日はUnityユーザーにしかわからないネタでした




ではでは
スポンサーサイト

2012/05/11 19:27 |プログラムCOMMENT(0)TRACKBACK(0)  

コメント

コメントの投稿



管理者にだけ表示を許可する

 | BLOG TOP | 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。