编写:徐建祥(netpirate@gmail.com)
日期:2010/12/06
网址:http://www.anymobile.org
传输文件,或者设置头像,我们一般都会检查原始图片的大小,作缩放处理。
常用的Java版缩放图片代码:
- public Bitmap getZoomImage(Bitmap src, int desW, int desH)
- {
- Bitmap desImg = null;
- int srcW = src.getWidth();
- int srcH = src.getHeight();
- int[] srcBuf = new int[srcW * srcH];
-
- src.getPixels(srcBuf, 0, srcW, 0, 0, srcW, srcH);
-
-
- int[] tabY = new int[desH];
- int[] tabX = new int[desW];
-
- int sb = 0;
- int db = 0;
- int tems = 0;
- int temd = 0;
- int distance = srcH > desH ? srcH : desH;
- for (int i = 0; i <= distance; i++)
- {
- tabY[db] = sb;
- tems += srcH;
- temd += desH;
- if (tems > distance)
- {
- tems -= distance;
- sb++;
- }
- if (temd > distance)
- {
- temd -= distance;
- db++;
- }
- }
-
- sb = 0;
- db = 0;
- tems = 0;
- temd = 0;
- distance = srcW > desW ? srcW : desW;
-
- for (int i = 0; i <= distance; i++)
- {
- tabX[db] = (short) sb;
- tems += srcW;
- temd += desW;
- if (tems > distance)
- {
- tems -= distance;
- sb++;
- }
- if (temd > distance)
- {
- temd -= distance;
- db++;
- }
- }
-
-
- int[] desBuf = new int[desW * desH];
- int dx = 0;
- int dy = 0;
- int sy = 0;
- int oldy = -1;
-
- for (int i = 0; i < desH; i++)
- {
- if (oldy == tabY[i])
- {
- System.arraycopy(desBuf, dy - desW, desBuf, dy, desW);
- }
- else
- {
- dx = 0;
- for (int j = 0; j < desW; j++)
- {
- desBuf[dy + dx] = srcBuf[sy + tabX[j]];
- dx++;
- }
- sy += (tabY[i] - oldy) * srcW;
- }
- oldy = tabY[i];
- dy += desW;
- }
-
- desImg = Bitmap.createBitmap(desBuf, desW, desH, Bitmap.Config.ARGB_8888);
-
- return desImg;
- }
常用的Android版缩放图片代码:
- ContentResolver cr = this.getContentResolver();
- try
- {
- InputStream in = cr.openInputStream(uri);
- Bitmap bitmap = BitmapFactory.decodeStream(in);
- try
- {
- in.close();
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- if(null == bitmap)
- {
- Toast.makeText(this, "Head is not set successful,Decode bitmap failure", 2000);
- }
-
- int bmpWidth = bitmap.getWidth();
- int bmpHeight = bitmap.getHeight();
-
-
- float scaleWidth = (float) 40 / bmpWidth;
- float scaleHeight = (float) 40 / bmpHeight;
- Matrix matrix = new Matrix();
- matrix.postScale(scaleWidth, scaleHeight);
-
-
- Bitmap resizeBitmap = Bitmap.createBitmap(
- bitmap, 0, 0, bmpWidth, bmpHeight, matrix, false);
- bitmap.recycle();
-
- byte[] photoData = Bitmap2Bytes(resizeBitmap);
-
-
- String fileName = "/sdcard/test.jpg";
- FileUtil.writeToFile(fileName, photoData);
-
-
- DataCenter.GetInstance().ModifyIMMUser();
-
- }
- catch (FileNotFoundException exp)
- {
- exp.printStackTrace();
- }
如果图片非常大,在执行BitmapFactory.decodeStream的时候就会抛出OOM异常。
我们来看看系统应用MMS是如何处理的,SMS添加了多媒体附件后就作MMS处理了,当附加文件原图超过300K,也会做个缩放处理,具体参考:com.android.mms.ui/.UriImage:
- package com.android.mms.ui;
- public class UriImage
- {
- private int mWidth;
- private int mHeight;
- ... ...
-
- private void decodeBoundsInfo()
- {
- InputStream input = null;
- try
- {
- input = mContext.getContentResolver().openInputStream(mUri);
- BitmapFactory.Options opt = new BitmapFactory.Options();
- opt.inJustDecodeBounds = true;
- BitmapFactory.decodeStream(input, null, opt);
- mWidth = opt.outWidth;
- mHeight = opt.outHeight;
- }
- catch (FileNotFoundException e)
- {
-
- Log.e(TAG, "IOException caught while opening stream", e);
- }
- finally
- {
- if (null != input) {
- try {
- input.close();
- } catch (IOException e) {
-
- Log.e(TAG, "IOException caught while closing stream", e);
- }
- }
- }
- }
- private byte[] getResizedImageData(int widthLimit, int heightLimit)
- {
- int outWidth = mWidth;
- int outHeight = mHeight;
- int s = 1;
- while ((outWidth / s > widthLimit) || (outHeight / s > heightLimit))
- {
- s *= 2;
- }
-
- BitmapFactory.Options options = new BitmapFactory.Options();
-
- options.inSampleSize = s;
- InputStream input = null;
- try
- {
- input = mContext.getContentResolver().openInputStream(mUri);
- Bitmap b = BitmapFactory.decodeStream(input, null, options);
- if (b == null) {
- return null;
- }
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- b.compress(CompressFormat.JPEG, MessageUtils.IMAGE_COMPRESSION_QUALITY, os);
- return os.toByteArray();
- } catch (FileNotFoundException e) {
- Log.e(TAG, e.getMessage(), e);
- return null;
- } finally {
- if (input != null) {
- try {
- input.close();
- } catch (IOException e) {
- Log.e(TAG, e.getMessage(), e);
- }
- }
- }
- }
- ... ...
- }
可以看出,MMS应用的方法是:先设置缩放选项,再读取缩放的图片数据到内存,规避了内存引起的OOM。
修改后的代码:
- ContentResolver cr = this.getContentResolver();
- try
- {
- InputStream in = cr.openInputStream(uri);
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeStream(in, null, options);
- try
- {
- in.close();
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- int mWidth = options.outWidth;
- int mHeight = options.outHeight;
-
- int sWidth = 40;
- int sHeight = 40;
-
- int s = 1;
- while ((mWidth / s > sWidth * 2) || (mHeight / s > sHeight * 2))
- {
- s *= 2;
- }
- options = new BitmapFactory.Options();
- options.inSampleSize = s;
- in = cr.openInputStream(uri);
- Bitmap bitmap = BitmapFactory.decodeStream(in, null, options);
- try
- {
- in.close();
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- if(null == bitmap)
- {
- Toast.makeText(this, "Head is not set successful,Decode bitmap failure", 2000);
- return ;
- }
-
- int bmpWidth = bitmap.getWidth();
- int bmpHeight = bitmap.getHeight();
-
-
- float scaleWidth = (float) sWidth / bmpWidth;
- float scaleHeight = (float) sHeight / bmpHeight;
- Matrix matrix = new Matrix();
- matrix.postScale(scaleWidth, scaleHeight);
-
-
- Bitmap resizeBitmap = Bitmap.createBitmap(
- bitmap, 0, 0, bmpWidth, bmpHeight, matrix, false);
- bitmap.recycle();
- Bitmap resizeBitmap = bitmap;
-
- byte[] photoData = bitmap2Bytes(resizeBitmap);
-
-
- String fileName = "/sdcard/test.jpg";
- FileUtil.writeToFile(fileName, photoData);
- private byte[] bitmap2Bytes(Bitmap bm)
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
- return baos.toByteArray();
- }
OVER!
posted on 2010-12-14 23:10
Xu Jianxiang 阅读(4039)
评论(0) 编辑 收藏 所属分类:
Android