Nanashi-softプログラマ専用Photoshopプラグイン開発


◇Photoshopプラグイン開発 -16bit画像減色(2-

●画面全体が暗くなるのを改善したい

小さい画像で見るとよくわからないかも知れませんが,画面全体に表示していると,なんだか暗くなったように感じます
後ろ 4bit分のデータを削除しているので,それは当たり前の事だと思います

ふと思いました。画像仕様を策定する人が真っ白を切り捨てるだろうか?
真っ黒と真っ白はとても重要な色ですよね?
今のロジックだと,真っ白である 0xffは,0xf0になってしまいます

かなり単純なロジックで,0xffを消さないようにしてみました
if(0xff < (int)*pixel + (int)amari[color]){
	*pixel = 0xff;
}else{
	*pixel = *pixel + amari[color];
}
amari[color] = *pixel & 0x0f;

if(*pixel & 0x08){
	*pixel = *pixel | 0x0f;	//5bit目がある場合はビットを埋める
}else{
	*pixel = *pixel & 0xf0;
}

Unity3D上で ETC1フォーマット圧縮をかけて表示したものです
明るさが随分と改善されている事がわかります

●画面全体が暗くなるのを改善したい(再調整)

このままだと,加算しすぎになってしまっています
ビットを埋めた時には,その分を次のドットで引かなければなりません

余りを保持するスタティック変数を,マイナス値も使える型に変更
static int8 amari[4]={0,0,0,0};    //uint8→int8に変更
後ろ 4bit分を保持する変数ですので,8bitのままでOKです

後ろ 4bitをカットする時は今まで通りで,ビットを埋める場合にその分をマイナス値で保存します
if(0xff < (int)*pixel + (int)amari[color]){
	*pixel = 0xff;
}else if((int)*pixel + (int)amari[color] < 0){	//マイナス値が来るようになったので,0未満になる場合を考慮する
	*pixel = 0x00;
}else{
	*pixel = *pixel + amari[color];
}

if(*pixel & 0x08){
	amari[color] = -0x0f + (*pixel & 0x0f);	//加算した分をマイナスする
	*pixel = *pixel | 0x0f;
}else{
	amari[color] = *pixel & 0x0f;	//今まで通り
	*pixel = *pixel & 0xf0;
}

●ディザリングを抑制したい

このロジックには弱点があります
例えば,R179 G86 B86で塗りつぶした画像に対して実行すると,縞模様が出来てしまいます
このカラーは 16bit画像では表せないので間違いではありません。遠めにはほぼ同じ色に見える事でしょう

ただ,画面全体にディザリングがかかっていると,やっぱりザラザラした感じになってしまいます
それを抑制するには,同一色が続いた場合は余りを加算する処理をしない,ことで可能でしょう

1つ前のドットを保存する場所を作る
static uint8 oldcolor[4]={0,0,0,0};	//1つ前のドットの色

uint8 savecolor=*pixel;	//現在のドット情報を退避
if(*pixel != oldcolor[color]){	//1つ前のドットと同じで無い場合のみ処理
	if(0xff < (int)*pixel + (int)amari[color]){
		*pixel = 0xff;
	}else if((int)*pixel + (int)amari[color] < 0){
		*pixel = 0x00;
	}else{
		*pixel = *pixel + amari[color];
	}
}
oldcolor[color]=savecolor;	//退避しておいた元のドットを保存
これで先ほどの中間色で塗りつぶした画像に縞模様は出なくなります
ただし,後ろ4bitを触りますので,同じ色では無くなります



TOPプログラマ専用Photoshopプラグイン開発