Android上Bitmap文件解析示例

来源:互联网 发布:淘宝手机市场 编辑:程序博客网 时间:2024/05/21 04:21

本文主要介绍的是Bitmap文件解析的一个简单示例,例子是在Androd上写的,用到的图像只有24位深度的这一种。

Bitmap文件的基本结构参考:
http://www.cnblogs.com/jerry-lin300/archive/2011/12/16/2233854.html

例子中用到的原始Bitmap图片:
这里写图片描述

主要过程就是加载Bitmap图片进行解析,简单的灰度处理,转换成Android中Bitmap对象,然后显示出来。

截图:
这里写图片描述

在分析Bitmap结构过程中可以利用 BMPAnalyzer 这个小工具,上面会显示出主要的参数:
这里写图片描述

Bitmap算是最简单的图像格式了,解析也比较简单,有几点注意下就好了:
1.文件信息中各字段是采用大端还是小端存储的;
2.图像内容读取的顺序(biHeight的正负),一般是从左下角开始按行读取;
3.字节补齐的问题,每行4个字节整数倍存储;
4.文件解析的时候考虑有无调色板(颜色表)。

下面是代码:

package com.ysm.bmp;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import android.os.AsyncTask;import android.os.Bundle;import android.app.Activity;import android.graphics.Bitmap;import android.util.Log;import android.widget.ImageView;public class MainActivity extends Activity {    private ImageView mResultView;    public int mWidth;    public int mHeight;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mResultView = (ImageView) findViewById(R.id.result_image);        new BmpConvertTask().execute();    }    private byte[] loadBmpFile() throws IOException {        InputStream is = getResources().getAssets().open("stone.bmp");         ByteArrayOutputStream bytestream = new ByteArrayOutputStream();        int ch;        while ((ch = is.read()) != -1) {            bytestream.write(ch);        }        byte imgdata[] = bytestream.toByteArray();        bytestream.close();        return imgdata;    }    private int[] bitmapFilter(byte[] fileBytes) {        /**************** bitmap file head *******************/        int offset = 0;        //"BM"        //int BM = fileBytes[offset+1] & 0xff;        //BM = (BM << 8) | (fileBytes[offset] & 0xff) ;        offset += 2;        //bfSize        int fileSize = fileBytes[offset+3] & 0xff;        fileSize = (fileSize << 8) | (fileBytes[offset+2] & 0xff);        fileSize = (fileSize << 8) | (fileBytes[offset+1] & 0xff);        fileSize = (fileSize << 8) | (fileBytes[offset] & 0xff);        offset += 4;        //bfReserved1        offset += 2;        //bfReserved2        offset += 2;        //bfOffsetBits, the offset, i.e. starting address,         //of the byte where the bitmap image data (Pixel Array) can be found.        int dataOffset = fileBytes[offset+3] & 0xff;        dataOffset = (dataOffset << 8) | (fileBytes[offset+2] & 0xff);        dataOffset = (dataOffset << 8) | (fileBytes[offset+1] & 0xff);        dataOffset = (dataOffset << 8) | (fileBytes[offset] & 0xff);        offset += 4;        /**************** DIB head *******************/        //biSize, the size of this header (40 bytes)        int dibHeadSize = fileBytes[offset+3] & 0xff;        dibHeadSize = (dibHeadSize << 8) | (fileBytes[offset+2] & 0xff);        dibHeadSize = (dibHeadSize << 8) | (fileBytes[offset+1] & 0xff);        dibHeadSize = (dibHeadSize << 8) | (fileBytes[offset] & 0xff);        offset += 4;        //biWidth, the bitmap width in pixels (signed integer).        int bWidth = fileBytes[offset+3] & 0xff;        bWidth = (bWidth << 8) | (fileBytes[offset+2] & 0xff);        bWidth = (bWidth << 8) | (fileBytes[offset+1] & 0xff);        bWidth = (bWidth << 8) | (fileBytes[offset] & 0xff);        offset += 4;        //biHeight, the bitmap height in pixels (signed integer).        int bHeight = fileBytes[offset+3] & 0xff;        bHeight = (bHeight << 8) | (fileBytes[offset+2] & 0xff);        bHeight = (bHeight << 8) | (fileBytes[offset+1] & 0xff);        bHeight = (bHeight << 8) | (fileBytes[offset] & 0xff);        offset += 4;        //biPlanes, the number of color planes being used. Must be set to 1.        offset += 2;        //biBitCount, the number of bits per pixel, which is the color depth of the image.        //Typical values are 1, 4, 8, 16, 24 and 32.        int bitDepth = fileBytes[offset+1] & 0xff;        bitDepth = (bitDepth << 8) | (fileBytes[offset] & 0xff);        offset += 2;        //biCompression, the compression method being used.        int bCompress = fileBytes[offset+3] & 0xff;        bCompress = (bCompress << 8) | (fileBytes[offset+2] & 0xff);        bCompress = (bCompress << 8) | (fileBytes[offset+1] & 0xff);        bCompress = (bCompress << 8) | (fileBytes[offset] & 0xff);        offset += 4;        //biImageSize, the image size, this will be padded to 4 bytes in row.        int imageSize = fileBytes[offset+3] & 0xff;        imageSize = (imageSize << 8) | (fileBytes[offset+2] & 0xff);        imageSize = (imageSize << 8) | (fileBytes[offset+1] & 0xff);        imageSize = (imageSize << 8) | (fileBytes[offset] & 0xff);        offset += 4;        //biXPixelsPerMeter, the horizontal resolution of the image. (pixel per meter, signed integer)        int xRes = fileBytes[offset+3] & 0xff;        xRes = (xRes << 8) | (fileBytes[offset+2] & 0xff);        xRes = (xRes << 8) | (fileBytes[offset+1] & 0xff);        xRes = (xRes << 8) | (fileBytes[offset] & 0xff);        offset += 4;        //biXPixelsPerMeter, the horizontal resolution of the image. (pixel per meter, signed integer)        int yRes = fileBytes[offset+3] & 0xff;        yRes = (yRes << 8) | (fileBytes[offset+2] & 0xff);        yRes = (yRes << 8) | (fileBytes[offset+1] & 0xff);        yRes = (yRes << 8) | (fileBytes[offset] & 0xff);        offset += 4;        //biColorUesd, the number of colors in the color palette, or 0 to default to 2n.        int palette = fileBytes[offset+3] & 0xff;        palette = (palette << 8) | (fileBytes[offset+2] & 0xff);        palette = (palette << 8) | (fileBytes[offset+1] & 0xff);        palette = (palette << 8) | (fileBytes[offset] & 0xff);        offset += 4;        //biColorImportent, the number of important colors used, or 0 when every color is important; generally ignored.        int ci = fileBytes[offset+3] & 0xff;        ci = (ci << 8) | (fileBytes[offset+2] & 0xff);        ci = (ci << 8) | (fileBytes[offset+1] & 0xff);        ci = (ci << 8) | (fileBytes[offset] & 0xff);        offset += 4;        mWidth = bWidth;        mHeight = bHeight;        int test = bWidth * bHeight * bitDepth / 8;        Log.v("BitmapConvert", "bWidth: " + bWidth);        Log.v("BitmapConvert", "bHeight: " + bHeight);        Log.v("BitmapConvert", "test: " + test);        Log.v("BitmapConvert", "imageSize: " + imageSize);        Log.v("BitmapConvert", "fileSize: " + fileSize);        int byteCount = bitDepth / 8;        byte[] realByte = new byte[bWidth * bHeight * byteCount];        int extra = 4 - ((bWidth * byteCount) % 4);        int k = 0;        int count = 0;        int width = bWidth * byteCount + extra; //byte        for(int i = bHeight - 1;i >=0;i--) {            count = dataOffset + width * i;            for(int j = 0;j < width - extra;j++) {                realByte[k++] = fileBytes[count + j];            }        }        int[] realData = new int[bWidth * bHeight];        int n = 0;        int r, g, b, gray;        for(int i = 0;i < bHeight;i++) {            for(int j = 0;j < bWidth * byteCount;j+=byteCount) {                count = i * bWidth * byteCount + j;                r = realByte[count] & 0xff;                g = realByte[count+1] & 0xff;                b = realByte[count+2] & 0xff;                r = r>255 ? 255 : (r<0 ? 0 : r);                g = g>255 ? 255 : (g<0 ? 0 : g);                b = b>255 ? 255 : (b<0 ? 0 : b);                gray = (r + g + b) / 3;                //realData[n++] = 0xff000000 | (b<<16) |  (g<<8) | r;                realData[n++] = 0xff000000 | (gray<<16) |  (gray<<8) | gray;            }        }        return realData;    }    private class BmpConvertTask extends AsyncTask<Void, Void, Bitmap> {        Bitmap bitmap;        @Override        protected Bitmap doInBackground(Void... arg0) {            try {                byte[] b = loadBmpFile();                int[] r = bitmapFilter(b);                bitmap = Bitmap.createBitmap(r, mWidth, mHeight, Bitmap.Config.ARGB_8888);            } catch (IOException e) {                e.printStackTrace();            }            return bitmap;        }        @Override        protected void onPostExecute(Bitmap result) {            super.onPostExecute(result);            if(null != result) {                mResultView.setImageBitmap(result);            }        }    }}

示例下载:
http://download.csdn.net/detail/smileorcryps/9772671

0 0