天天看點

Png圖檔換色的方法

對于"索引類型的圖檔",即肯定包含PLTE調色闆的Png圖檔,就可以通過對調色闆的修改,再通過CRC算法生成新的驗證碼,再還原成新圖檔就可以得到所要的效果,為此,我寫了如下的類.

import Java.io.*;

import java.lang.*;

import javax.microedition.lcdui.*;

public class coloredImage {

    public coloredImage() {

    }

    public Image getColoredImage(String s, int newcolor) {

        try {

            byte[] pixel;

            InputStream is = getClass().getResourceAsStream(s);

            int i = 0;

            while (is.read() != -1) {

                i++;

            }

            pixel = new byte[i];

            is = null;

            is = getClass().getResourceAsStream(s);

            is.read(pixel);

            imgConvert(pixel, newcolor);

            return (Image.createImage(pixel, 0, pixel.length));

        } catch (Exception e) {

            return null;

        }

    }

    public void imgConvert(byte content[], int color) {

        try {

            int start = 0;

            int newcolor = -1;

           for (int idx = 0; idx < content.length; idx++) {

                if (content[idx] == 0x50 && content[idx + 1] == 0x4c

                    && content[idx + 2] == 0x54 && content[idx + 3] == 0x45) {

                    start = idx;

                    break;

                }

            }            for (int idx = 0; idx < 4; idx++) {

                newcolor = pixelConvert(content[start + idx], newcolor);

            }

            int r, g, b, length;

            length = (content[start - 4] & 0xff << 24) |

                     (content[start - 3] & 0xff << 16) |

                     (content[start - 2] & 0xff << 8) |

                     (content[start - 1] & 0xff);

            for (int i = 0; i < length; i++) {

                r = content[start + 4 + i] & 0xff;

                g = content[start + 4 + i + 1] & 0xff;

                b = content[start + 4 + i + 2] & 0xff;

                if (r == 255 && g == 0 && b == 0) {

                    r = color >> 16 & 0xff;

                    g = color >> 8 & 0xff;

                    b = color & 0xff;

                    content[start + 4 + i] = (byte) r;

                    content[start + 4 + i + 1] = (byte) g;

                    content[start + 4 + i + 2] = (byte) b;

                }

                newcolor = pixelConvert(content[start + 4 + i], newcolor);

                newcolor = pixelConvert(content[start + 4 + i + 1], newcolor);

                newcolor = pixelConvert(content[start + 4 + i + 2], newcolor);

            }

            newcolor = ~newcolor;

            content[start + 4 + length] = (byte) (newcolor >> 24);

            content[start + 4 + length + 1] = (byte) (newcolor >> 16);

            content[start + 4 + length + 2] = (byte) (newcolor >> 8);

            content[start + 4 + length + 3] = (byte) (newcolor);

        } catch (Exception e) {}

    }

    public int pixelConvert(byte pixel, int color) {

        int tmp = pixel & 0xff;

        color ^= tmp;

        for (int idx = 0; idx < 8; idx++) {

            if ((color & 1) != 0) {

                color = color >>> 1 ^ 0xedb88320;

            } else {

                color >>>= 1;

            }

        }

        return color;

    }

}這個類提供了一個轉換圖檔顔色的方法getColoredImage,隻要将源圖檔的路徑以及需要轉換的新顔色作為參數調用就可以得到轉換後的圖檔.

相應的我把我的主類寫出來供大家參考其用法. import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import java.util.*;

import com.nokia.mid.UI.*;

import java.io.*;

public class pengzhuang extends MIDlet {

    class test extends FullCanvas {

        Image[] a;

        byte[] pix;

        coloredImage ci;

        public test() {

            ci = new coloredImage();

            a = new Image[4];

            a[0] = ci.getColoredImage("/char.png", 0x0000ff);

            a[1] = ci.getColoredImage("/char.png", 0x00ff00);

            a[2] = ci.getColoredImage("/char.png", 0xffffff);

            a[3] = ci.getColoredImage("/char.png", 0x00ffff);

        }

        public void keyPressed(int i) {

        }

        public void paint(Graphics g) {

            g.setColor(0xffffff);

            g.fillRect(0, 0, getWidth(), getHeight());

            g.drawImage(a[0], 0, 0, 0);

            g.drawImage(a[1], 30, 30, 0);

            g.drawImage(a[2], 60, 60, 0);

            g.drawImage(a[3], 90, 90, 0);

        }

    }

    private Display display;

    test t;

    public pengzhuang() {

        try {

            t = new test();

        } catch (Exception e) {

        }

        display = Display.getDisplay(this);

    }

    public void startApp() {

        display.setCurrent(t);

    }

    public void pauseApp() {

    }

    public void destroyApp(boolean boo) {

    }

}

其中用到的源圖是

Png圖檔換色的方法

 Png圖檔換色的方法

運作程式後的效果為

Png圖檔換色的方法

  Png圖檔換色的方法