您现在的位置是:首页 >

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

火烧 2023-02-19 19:11:22 1063
关于游戏中高效的换色方法 众所周知 我们可以使用getRGB 取得取得图片的RGB颜色数据 然后修改RGB颜色数据 再用Image的静态方法createRGBImage 将修改后的RGB颜色数据生成新
换发色特效 关于游戏中高效的换色方法

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

    众所周知 我们可以使用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  
永远跟党走
  • 如果你觉得本站很棒,可以通过扫码支付打赏哦!

    • 微信收款码
    • 支付宝收款码