zoukankan      html  css  js  c++  java
  • layout中加载gif图片

    GIFView gif = new GIFView(LoadUI.this, R.drawable.progress);
    ((RelativeLayout) findViewById(R.id.progress)).addView(gif);

    GIFView.java

    package src.com.android.weather.util;

    import java.io.InputStream;

    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.view.View;

    public class GIFView extends View implements Runnable {

    private Bitmap bmb;
    private GIFDecode decode;

    public GIFView(Context context, int img) {
    super(context);
    decode = new GIFDecode();
    InputStream in = this.getResources().openRawResource(img);
    decode.read(in);
    bmb = decode.getFrame(0);
    Thread t = new Thread(this);
    t.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);
    canvas.drawBitmap(bmb, 0, 0, new Paint());
    bmb = decode.next();
    }

    @Override
    public void run() {
    // TODO Auto-generated method stub
    while(true){
    try {
    this.postInvalidate();
    Thread.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }

    }

    }

    GIFDecode.java

    package src.com.android.weather.util;

    import java.io.InputStream;
    import java.util.Vector;

    import android.graphics.Bitmap;
    import android.graphics.Bitmap.Config;

    public class GIFDecode {

    public static final int STATUS_OK = 0;
    public static final int STATUS_FORMAT_ERROR = 1;
    public static final int STATUS_OPEN_ERROR = 2;

    protected InputStream in;
    protected int status;

    protected int width; // full image width
    protected int height; // full image height
    protected boolean gctFlag; // global color table used
    protected int gctSize; // size of global color table
    protected int loopCount = 1; // iterations; 0 = repeat forever

    protected int[] gct; // global color table
    protected int[] lct; // local color table
    protected int[] act; // active color table

    protected int bgIndex; // background color index
    protected int bgColor; // background color
    protected int lastBgColor; // previous bg color
    protected int pixelAspect; // pixel aspect ratio

    protected boolean lctFlag; // local color table flag
    protected boolean interlace; // interlace flag
    protected int lctSize; // local color table size

    protected int ix, iy, iw, ih; // current image rectangle
    protected int lrx, lry, lrw, lrh;
    protected Bitmap image; // current frame
    protected Bitmap lastImage; // previous frame
    protected int frameindex = 0;

    public int getFrameindex() {
    return frameindex;
    }

    public void setFrameindex(int frameindex) {
    this.frameindex = frameindex;
    if (frameindex > frames.size() - 1) {
    frameindex = 0;
    }
    }

    protected byte[] block = new byte[256]; // current data block
    protected int blockSize = 0; // block size

    // last graphic control extension info
    protected int dispose = 0;
    // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev
    protected int lastDispose = 0;
    protected boolean transparency = false; // use transparent color
    protected int delay = 0; // delay in milliseconds
    protected int transIndex; // transparent color index

    protected static final int MaxStackSize = 4096;
    // max decoder pixel stack size

    // LZW decoder working arrays
    protected short[] prefix;
    protected byte[] suffix;
    protected byte[] pixelStack;
    protected byte[] pixels;

    @SuppressWarnings("unchecked")
    protected Vector frames; // frames read from current file
    protected int frameCount;

    static class GifFrame {

    public Bitmap image;
    public int delay;

    public GifFrame(Bitmap im, int del) {
    image = im;
    delay = del;
    }
    }

    /**
    * Gets display duration for specified frame.
    *
    */
    public int getDelay(int n) {
    delay = -1;
    if ((n >= 0) && (n < frameCount)) {
    delay = ((GifFrame) frames.elementAt(n)).delay;
    }
    return delay;
    }

    public int getFrameCount() {
    return frameCount;
    }

    public Bitmap getImage() {
    return getFrame(0);
    }

    public int getLoopCount() {
    return loopCount;
    }

    public void setPixels() {
    int[] dest = new int[width * height];
    // fill in starting image contents based on last image's dispose code
    if (lastDispose > 0) {
    if (lastDispose == 3) {
    // use image before last
    int n = frameCount - 2;
    if (n > 0) {
    lastImage = getFrame(n - 1);
    } else {
    lastImage = null;
    }
    }

    if (lastImage != null) {
    lastImage.getPixels(dest, 0, width, 0, 0, width, height);
    // copy pixels
    if (lastDispose == 2) {
    // fill last image rect area with background color
    int c = 0;
    if (!transparency) {
    c = lastBgColor;
    }
    for (int i = 0; i < lrh; i++) {
    int n1 = (lry + i) * width + lrx;
    int n2 = n1 + lrw;
    for (int k = n1; k < n2; k++) {
    dest[k] = c;
    }
    }
    }
    }
    }

    // copy each source line to the appropriate place in the destination
    int pass = 1;
    int inc = 8;
    int iline = 0;
    for (int i = 0; i < ih; i++) {
    int line = i;
    if (interlace) {
    if (iline >= ih) {
    pass++;
    switch (pass) {
    case 2:
    iline = 4;
    break;
    case 3:
    iline = 2;
    inc = 4;
    break;
    case 4:
    iline = 1;
    inc = 2;
    }
    }
    line = iline;
    iline += inc;
    }
    line += iy;
    if (line < height) {
    int k = line * width;
    int dx = k + ix; // start of line in dest
    int dlim = dx + iw; // end of dest line
    if ((k + width) < dlim) {
    dlim = k + width; // past dest edge
    }
    int sx = i * iw; // start of line in source
    while (dx < dlim) {
    // map color and insert in destination
    int index = ((int) pixels[sx++]) & 0xff;
    int c = act[index];
    if (c != 0) {
    dest[dx] = c;
    }
    dx++;
    }
    }
    }
    image = Bitmap.createBitmap(dest, width, height, Config.RGB_565);
    }

    public Bitmap getFrame(int n) {
    Bitmap im = null;
    if ((n >= 0) && (n < frameCount)) {
    im = ((GifFrame) frames.elementAt(n)).image;
    }
    return im;
    }

    public Bitmap next() {
    frameindex++;
    if (frameindex > frames.size() - 1) {
    frameindex = 0;
    }
    return ((GifFrame) frames.elementAt(frameindex)).image;
    }

    public int read(InputStream is) {
    init();
    if (is != null) {
    in = is;
    readHeader();
    if (!err()) {
    readContents();
    if (frameCount < 0) {
    status = STATUS_FORMAT_ERROR;
    }
    }
    } else {
    status = STATUS_OPEN_ERROR;
    }
    try {
    is.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    return status;
    }

    protected void decodeImageData() {
    int NullCode = -1;
    int npix = iw * ih;
    int available, clear, code_mask, code_size, end_of_information, in_code, old_code, bits, code, count, i, datum, data_size, first, top, bi, pi;

    if ((pixels == null) || (pixels.length < npix)) {
    pixels = new byte[npix]; // allocate new pixel array
    }
    if (prefix == null) {
    prefix = new short[MaxStackSize];
    }
    if (suffix == null) {
    suffix = new byte[MaxStackSize];
    }
    if (pixelStack == null) {
    pixelStack = new byte[MaxStackSize + 1];
    }
    // Initialize GIF data stream decoder.
    data_size = read();
    clear = 1 << data_size;
    end_of_information = clear + 1;
    available = clear + 2;
    old_code = NullCode;
    code_size = data_size + 1;
    code_mask = (1 << code_size) - 1;
    for (code = 0; code < clear; code++) {
    prefix[code] = 0;
    suffix[code] = (byte) code;
    }

    // Decode GIF pixel stream.
    datum = bits = count = first = top = pi = bi = 0;
    for (i = 0; i < npix;) {
    if (top == 0) {
    if (bits < code_size) {
    // Load bytes until there are enough bits for a code.
    if (count == 0) {
    // Read a new data block.
    count = readBlock();
    if (count <= 0) {
    break;
    }
    bi = 0;
    }
    datum += (((int) block[bi]) & 0xff) << bits;
    bits += 8;
    bi++;
    count--;
    continue;
    }
    // Get the next code.
    code = datum & code_mask;
    datum >>= code_size;
    bits -= code_size;

    // Interpret the code
    if ((code > available) || (code == end_of_information)) {
    break;
    }
    if (code == clear) {
    // Reset decoder.
    code_size = data_size + 1;
    code_mask = (1 << code_size) - 1;
    available = clear + 2;
    old_code = NullCode;
    continue;
    }
    if (old_code == NullCode) {
    pixelStack[top++] = suffix[code];
    old_code = code;
    first = code;
    continue;
    }
    in_code = code;
    if (code == available) {
    pixelStack[top++] = (byte) first;
    code = old_code;
    }
    while (code > clear) {
    pixelStack[top++] = suffix[code];
    code = prefix[code];
    }
    first = ((int) suffix[code]) & 0xff;
    // Add a new string to the string table,
    if (available >= MaxStackSize) {
    break;
    }
    pixelStack[top++] = (byte) first;
    prefix[available] = (short) old_code;
    suffix[available] = (byte) first;
    available++;
    if (((available & code_mask) == 0)
    && (available < MaxStackSize)) {
    code_size++;
    code_mask += available;
    }
    old_code = in_code;
    }

    // Pop a pixel off the pixel stack.
    top--;
    pixels[pi++] = pixelStack[top];
    i++;
    }
    for (i = pi; i < npix; i++) {
    pixels[i] = 0; // clear missing pixels
    }
    }

    protected boolean err() {
    return status != STATUS_OK;
    }

    protected void init() {
    status = STATUS_OK;
    frameCount = 0;
    frames = new Vector();
    gct = null;
    lct = null;
    }

    protected int read() {
    int curByte = 0;
    try {
    curByte = in.read();
    } catch (Exception e) {
    status = STATUS_FORMAT_ERROR;
    }
    return curByte;
    }

    protected int readBlock() {
    blockSize = read();
    int n = 0;
    if (blockSize > 0) {
    try {
    int count = 0;
    while (n < blockSize) {
    count = in.read(block, n, blockSize - n);
    if (count == -1) {
    break;
    }
    n += count;
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    if (n < blockSize) {
    status = STATUS_FORMAT_ERROR;
    }
    }
    return n;
    }

    protected int[] readColorTable(int ncolors) {
    int nbytes = 3 * ncolors;
    int[] tab = null;
    byte[] c = new byte[nbytes];
    int n = 0;
    try {
    n = in.read(c);
    } catch (Exception e) {
    e.printStackTrace();
    }
    if (n < nbytes) {
    status = STATUS_FORMAT_ERROR;
    } else {
    tab = new int[256]; // max size to avoid bounds checks
    int i = 0;
    int j = 0;
    while (i < ncolors) {
    int r = ((int) c[j++]) & 0xff;
    int g = ((int) c[j++]) & 0xff;
    int b = ((int) c[j++]) & 0xff;
    tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b;
    }
    }
    return tab;
    }

    protected void readContents() {
    // read GIF file content blocks
    boolean done = false;
    while (!(done || err())) {
    int code = read();
    switch (code) {
    case 0x2C: // image separator
    readImage();
    break;
    case 0x21: // extension
    code = read();
    switch (code) {
    case 0xf9: // graphics control extension
    readGraphicControlExt();
    break;
    case 0xff: // application extension
    readBlock();
    String app = "";
    for (int i = 0; i < 11; i++) {
    app += (char) block[i];
    }
    if (app.equals("NETSCAPE2.0")) {
    readNetscapeExt();
    } else {
    skip(); // don't care
    }
    break;
    default: // uninteresting extension
    skip();
    }
    break;
    case 0x3b: // terminator
    done = true;
    break;
    case 0x00: // bad byte, but keep going and see what happens
    break;
    default:
    status = STATUS_FORMAT_ERROR;
    }
    }
    }

    protected void readGraphicControlExt() {
    read(); // block size
    int packed = read(); // packed fields
    dispose = (packed & 0x1c) >> 2; // disposal method
    if (dispose == 0) {
    dispose = 1; // elect to keep old image if discretionary
    }
    transparency = (packed & 1) != 0;
    delay = readShort() * 10; // delay in milliseconds
    transIndex = read(); // transparent color index
    read(); // block terminator
    }

    protected void readHeader() {
    String id = "";
    for (int i = 0; i < 6; i++) {
    id += (char) read();
    }
    if (!id.startsWith("GIF")) {
    status = STATUS_FORMAT_ERROR;
    return;
    }
    readLSD();
    if (gctFlag && !err()) {
    gct = readColorTable(gctSize);
    bgColor = gct[bgIndex];
    }
    }

    protected void readImage() {
    ix = readShort(); // (sub)image position & size
    iy = readShort();
    iw = readShort();
    ih = readShort();
    int packed = read();
    lctFlag = (packed & 0x80) != 0; // 1 - local color table flag
    interlace = (packed & 0x40) != 0; // 2 - interlace flag
    // 3 - sort flag
    // 4-5 - reserved
    lctSize = 2 << (packed & 7); // 6-8 - local color table size
    if (lctFlag) {
    lct = readColorTable(lctSize); // read table
    act = lct; // make local table active
    } else {
    act = gct; // make global table active
    if (bgIndex == transIndex) {
    bgColor = 0;
    }
    }
    int save = 0;
    if (transparency) {
    save = act[transIndex];
    act[transIndex] = 0; // set transparent color if specified
    }
    if (act == null) {
    status = STATUS_FORMAT_ERROR; // no color table defined
    }
    if (err()) {
    return;
    }
    decodeImageData(); // decode pixel data
    skip();
    if (err()) {
    return;
    }
    frameCount++;
    // create new image to receive frame data
    image = Bitmap.createBitmap(width, height, Config.RGB_565);
    // createImage(width, height);
    setPixels(); // transfer pixel data to image
    frames.addElement(new GifFrame(image, delay)); // add image to frame
    // list
    if (transparency) {
    act[transIndex] = save;
    }
    resetFrame();
    }

    protected void readLSD() {
    // logical screen size
    width = readShort();
    height = readShort();
    // packed fields
    int packed = read();
    gctFlag = (packed & 0x80) != 0; // 1 : global color table flag
    // 2-4 : color resolution
    // 5 : gct sort flag
    gctSize = 2 << (packed & 7); // 6-8 : gct size
    bgIndex = read(); // background color index
    pixelAspect = read(); // pixel aspect ratio
    }

    protected void readNetscapeExt() {
    do {
    readBlock();
    if (block[0] == 1) {
    // loop count sub-block
    int b1 = ((int) block[1]) & 0xff;
    int b2 = ((int) block[2]) & 0xff;
    loopCount = (b2 << 8) | b1;
    }
    } while ((blockSize > 0) && !err());
    }

    protected int readShort() {
    // read 16-bit value, LSB first
    return read() | (read() << 8);
    }

    protected void resetFrame() {
    lastDispose = dispose;
    lrx = ix;
    lry = iy;
    lrw = iw;
    lrh = ih;
    lastImage = image;
    lastBgColor = bgColor;
    dispose = 0;
    transparency = false;
    delay = 0;
    lct = null;
    }

    /**
    * Skips variable length blocks up to and including next zero length block.
    */
    protected void skip() {
    do {
    readBlock();
    } while ((blockSize > 0) && !err());
    }
    }

  • 相关阅读:
    怎么分辨是eclipse还是 android studio开发的
    一个帖子学会Android开发四大组件
    Android Studio ADB响应失败解决方法
    500 OOPS: could not read chroot() list file:/etc/vsftpd/chroot_list
    理解 with递归调用 Sqlserver 树查询
    SQLServer树查询
    数字证书原理【转】
    linux 基础命令
    项目经验分享[转自min.jiang]
    ios
  • 原文地址:https://www.cnblogs.com/xingmeng/p/2541558.html
Copyright © 2011-2022 走看看