换发色特效 关于游戏中高效的换色方法

关于游戏中高效的换色方法
众所周知 我们可以使用getRGB()取得取得图片的RGB颜色数据 然后修改RGB颜色数据 再用Image的静态方法createRGBImage()将修改后的RGB颜色数据生成新的png图片 但是这个方法效率低不说 而且就目前来说 如果要做中国市场 还得使用MIDP 所以今天我想谈一下另外一种换色方式 通过修改调色板数据来达到换色的目的 记得以前我在论坛发过一篇关于换色和旋转图片的文章 但是那次仅仅限于讨论 这次要说的是我已经应用在实际游戏当中的换色方法首先 我们取得png图片的二进制数据 修改其中的调色板域(PLTE chunk)数据 再使用createImage(byte[] imageData int imageOffset int imageLength)将修改后的二进制数据生成新的png对象 (换色是基于对图像格式的熟悉来进行的 所以你必须先了解PNG图片的格式 这个可以参考)
下面是获得图片调色板数据的方法(感谢飘飘白云的代码)
/** * 修改png图片的调色板数据生成新的png图片 * @param imageSrc png图片的二进制数据字节数组 * @return 修改后的png图片 */ public Image getPLTEModifidImage(byte[] imageSrc) { if (imageSrc == null || imageSrc length <= ) return null; if (crcTable == null) makeCrcTable(); // PLTE chunk数据域的类型标识 // see # PLTE String[] sPLTE = { c }; int i j; int pos = startPos = ; byte[] data = imageSrc; for (i = ; i < data length; i++) { if (Integer toHexString(data[i]) equals(sPLTE[ ]) && Integer toHexString(data[i + ]) equals(sPLTE[ ]) && Integer toHexString(data[i + ]) equals(sPLTE[ ]) && Integer toHexString(data[i + ]) equals(sPLTE[ ])) { pos = i; break; } } pos = ; startPos = pos;
// 取得PLTE chunk数据域的数据长度() int imageNbColors = ( ((data[pos] << ) & xff ) | ((data[pos + ] << ) & x ff ) | ((data[pos + ] << ) & x ff ) | ((data[pos + ] ) & x ff)); // 计算的PLTE chunk数据个数(每个PLTE chunk数据由R G B三个字节数据组成) imageNbColors = imageNbColors/ ; // 为整形的PLTE chunk data分配空间 int imageRGBColors[] = new int[ imageNbColors ]; // = 数据长度( 个字节) + 类型标识( 个字节) + 校验码( 个字节) // for( i = pos j = ; i < pos + + imageNbColors * ; i++ j++ ){// if( j >= && (j )% == ) {// println( );// }// System out print( + data[i]);// } pos += ;// println( n The number of PLTE chunks is + imageNbColors + ); if (imageRGBColors == null) return null; // 生成整形的PLTE chunk data for( i = ; i < imageNbColors; i++ ) { imageRGBColors[i] = ( (data[pos + ] & x ff) << ) | ((data[pos + ] & x ff) << ) | ((data[pos + ] & x ff));
pos += ; } // 修改 PLTE chunk data int l r g b; // gray for (j = ; j < imageNbColors; j++) { r = imageRGBColors[j]; g = (r & x FF ) >> ; b = r & x FF; r = (r & xFF ) >> ; l = (b + g * + r * ) / ; imageRGBColors[j] = l << | l << | l; } break; // 生成新的 PLTE chunk data pos = startPos + ; for( i = ; i < imageNbColors ;i++) { data[pos ] = (byte)((imageRGBColors[i] >> ) ) ; data[pos + ] = (byte)((imageRGBColors[i] >> ) ); data[pos + ] = (byte)(imageRGBColors[i] ); pos += ; } // 更新 CRC 校验码 int crc = updateCrcChunk( data startPos + startPos + + + ( imageNbColors * ) ); data[pos + ] = (byte)(crc >> & x FF); data[pos + ] = (byte)(crc >> & x FF); data[pos + ] = (byte)(crc >> & x FF); data[pos + ] = (byte)(crc & x FF); pos = startPos;
return Image createImage(data data length); }
其实这个方法只能简单得修改图片颜色 更好效率更高的方法是 做一个小工具将原图片的调色板数据提取出来 然后需要换的各种颜色 全部事先导成调色板数据文件 程序里面做的是只是根据需要合并这些数据组成各种图片
lishixinzhi/Article/program/Java/JSP/201311/19464