日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

使用調(diào)色板修改png圖片

 偶爾瘋狂 2013-02-21


這個算法是參考一位高人的文章,直接讀取并修改png格式圖片的調(diào)色板,然后生成新的調(diào)色板替代原來的。
這樣可以實現(xiàn)游戲中常見的變色效果,可以解決游戲容量有限,不能存放太多精靈圖片的問題。

具體過程其實并不復雜,大家可以先搜索資料,先看看png圖片的格式定義。這個算法正是找到調(diào)色板區(qū),根據(jù)原有格式修改之后,生成新的crc校驗碼,然后替換原來的調(diào)色板。這樣就可以用一個png圖片,創(chuàng)建多個變色副本。

public class PalettedImage {
 
    public Image getPalettedImage(byte[] data, int[] originalColors,
                                  int[] palettedColors) {
        byte[] tempData = new byte[data.length];
        System.arraycopy(data, 0, tempData, 0, data.length);
        Image img = null;
        int[] parameter = {0, 0, 0};
        analyze(tempData, parameter);
        for (int i = 0; i < originalColors.length; i++) {
            replaceColor(tempData, parameter, originalColors[i],
                         palettedColors[i]);
        }
        fillData(tempData, parameter);
        try {
            img = Image.createImage(tempData, 0, data.length);
        } catch (Exception e) {
            System.out.println("getPalettedImage  &&  " + e.toString());
        }
        return img;
    }
 
    private void analyze(byte[] data, int[] para) {
        int offset = 8;
        int chunkLen = 0;
        while (data[offset + 4] != 0x50 || data[offset + 5] != 0x4c
               || data[offset + 6] != 0x54 || data[offset + 7] != 0x45) {
            chunkLen = readInt(data, offset);
            offset += (4 + 4 + chunkLen + 4);
        }
        chunkLen = readInt(data, offset);
        para[2] = chunkLen / 3;
        para[0] = offset + 8;
        para[1] = offset + 8 + chunkLen;
    }
 
    private int readInt(byte[] data, int offset) {
        return ((data[offset] & 0xFF) << 24)
                | ((data[offset + 1] & 0xFF) << 16)
                | ((data[offset + 2] & 0xFF) << 8) | (data[offset + 3] & 0xFF);
    }
 
    private void replaceColor(byte[] data, int[] para, int oldColor,
                              int newColor) {
        byte rr = (byte) ((oldColor >> 16) & 0xff);
        byte gg = (byte) ((oldColor >> 8) & 0xff);
        byte bb = (byte) (oldColor & 0xff);
        for (int i = 0, offset = para[0], temp = 0; i < para[2]; i++,
                                                 offset += 3) {
            if (rr == data[offset] && gg == data[offset + 1]
                && bb == data[offset + 2]) {
                data[offset] = (byte) ((newColor >> 16) & 0xff);
                data[offset + 1] = (byte) ((newColor >> 8) & 0xff);
                data[offset + 2] = (byte) (newColor & 0xff);
                break;
            }
        }
    }
 
    private void fillData(byte[] data, int[] para) {
        int checksum = update_crc(data, para[0] - 4, para[2] * 3 + 4);
        data[para[1]] = (byte) ((checksum >> 24) & 0xff);
        data[para[1] + 1] = (byte) ((checksum >> 16) & 0xff);
        data[para[1] + 2] = (byte) ((checksum >> 8) & 0xff);
        data[para[1] + 3] = (byte) ((checksum) & 0xff);
    }
 
    private int update_crc(byte[] buf, int off, int len) {
        int c = 0xffffffff;
        int n, k;
        int xx;
        int[] crc_table = new int[256];
        for (n = 0; n < 256; n++) {
            xx = n;
            for (k = 0; k < 8; k++) {
                if ((xx & 1) == 1) {
                    xx = 0xedb88320 ^ (xx >>> 1);
                } else {
                    xx = xx >>> 1;
                }
            }
            crc_table[n] = xx;
        }
 
        for (n = off; n < len + off; n++) {
            c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >>> 8);
        }
        return (c ^ 0xffffffff);
    }
 
}

 接口就是getPalettedImage()函數(shù),只需要輸入原始圖片的byte數(shù)組,以及需要替換顏色的顏色值還有目標顏色值就行了。因為可以同時替換多個顏色,所以輸入?yún)?shù)是代表顏色的整形的數(shù)組。總之,要保證原始顏色與目標顏色一一對應(yīng)就好了。方法簡單實用。

 


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多