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