熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

關於游戲中高效的換色方法

2013-11-15 11:42:05  來源: JSP教程 
    眾所周知我們可以使用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);
              }

  其實這個方法只能簡單得修改圖片顏色更好效率更高的方法是做一個小工具將原圖片的調色板數據提取出來然後需要換的各種顏色全部事先導成調色板數據文件程序裡面做的是只是根據需要合並這些數據組成各種圖片

  歡迎大家繼續探討


From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19464.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.