Android 内存抖动 性能分析 <10>
2016-01-14 00:35
579 查看
最近刚好做图形处理方面,对图片像素进行处理,可想而知,一张图片如800*800的,那么像素点就有640000个,如果对这么大的一个数据进行运算操作,将会消耗大量内存空间,下面是自己在处理一张图片,让这张图片调整成一张老照片效果,具体操作如下:
<1> : 新建Android工程如下:
<2> : 工程里面还有其他的代码,这里只给出主要涉及的:
DurianMainActivity.java
package org.durian.duriangaussian;
import android.app.Activity;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
public class DurianMainActivity extends Activity {
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.durian_main);
imageView=(ImageView)findViewById(R.id.image);
imageView.setImageBitmap(BitmapFactory.decodeResource(this.getResources(),R.drawable.ghh));
}
}
DurianGaussView.java
上面有两个工作线程,这里屏蔽其中一个功能.
DurianOldPhotoEffort.java
package org.durian.duriangaussian;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
/**
* Created by Administrator on 2016/1/13.
*/
public class DurianOldPhotoEffort {
private final static String TAG="DurianOldPhotoEffort";
public static Bitmap makeOldPhotoEffort(Context context){
Bitmap bitmap= BitmapFactory.decodeResource(context.getResources(),R.drawable.ghh);
int bitmapWidth=bitmap.getWidth();
int bitmapHeight=bitmap.getHeight();
int pixLength=bitmapHeight*bitmapWidth;
int inPixs[]=new int[pixLength];
int outPixs[]=new int[pixLength];
int tr=0,tg=0,tb=0,ta=0;
int index=0;
int color=0;
Log.i(TAG, "123**********************");
for (int row=0;row<bitmapHeight;row++){
for (int col=0;col<bitmapWidth;col++){
index=row*bitmapWidth+col;
color=bitmap.getPixel(col,row);
inPixs[index]=color;
}
}
Log.i(TAG, "456**********************");
int fr=0,fg=0,fb=0;
int rows=0,cols=0;
for (rows=0;rows<bitmapHeight;rows++){
tr=0;tg=0;tb=0;ta=0;
for (cols=0;cols<bitmapWidth;cols++){
index=rows*bitmapWidth+cols;
ta=(inPixs[index]>>24) & 0xFF;
tr=(inPixs[index]>>16) & 0xFF;
tg=(inPixs[index]>>8) & 0xFF;
tb=(inPixs[index]) & 0xFF;
//
/*int fr=(int)colorBlend(noise(),(tr*0.393)+(tg*0.769)+(tb*0.189),tr);
int fg=(int)colorBlend(noise(),(tr*0.349)+(tg*0.686)+(tb*0.168),tg);
int fb=(int)colorBlend(noise(),(tr*0.272)+(tg*0.534)+(tb*0.131),tb);*/
fr=(int)colorBlend(noise(),(tr*0.393)+(tg*0.769)+(tb*0.189),tr);
fg=(int)colorBlend(noise(),(tr*0.349)+(tg*0.686)+(tb*0.168),tg);
fb=(int)colorBlend(noise(),(tr*0.272)+(tg*0.534)+(tb*0.131),tb);
outPixs[index]=(ta<<24) | (clamp(fr)<<16) | (clamp(fg)<<8) | clamp(fb);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
bitmap.setPixel(cols,rows,outPixs[index]);
}
}
Log.i(TAG, "789**********************");
return bitmap;
};
private static double noise(){
return Math.random()*0.5+0.5;
}
private static double colorBlend(double scale,double dest,double src){
return (scale*dest+(1.0-scale)*src);
}
private static int clamp(int c){
return c>255?255:((c<0)?0:c);
}
public String toString(){
return "Effect from Photoshop App !";
}
}
布局文件:
里面用到的图片:
<3> : 运行的结果,图片将不会被处理,控制台一直报:
<4> : 内存图:
右上角的Free和Allocated 旁边内存量大小将不断的变化,从上面的图形来看,内存抖动的非常厉害.
<5> : 解决上面的内存抖动,首先想到的是可能是下面导致的:
所以把这里和相关的代码全部用到fr,fg等地方全部屏蔽掉,但是再次运行的时候发现还是不行.
继续查找:
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
bitmap.setPixel(cols,rows,outPixs[index]);发现这段代码的确有问题,bitmap反复copy,我靠,有点低级错误呀.看来需要把这一句代码放在for循环外面:
调整为:
Log.i(TAG, "456**********************");
int fr=0,fg=0,fb=0;
int rows=0,cols=0;
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
for (rows=0;rows<bitmapHeight;rows++){
tr=0;tg=0;tb=0;ta=0;
for (cols=0;cols<bitmapWidth;cols++){
index=rows*bitmapWidth+cols;
ta=(inPixs[index]>>24) & 0xFF;
tr=(inPixs[index]>>16) & 0xFF;
tg=(inPixs[index]>>8) & 0xFF;
tb=(inPixs[index]) & 0xFF;
fr=(int)colorBlend(noise(),(tr*0.393)+(tg*0.769)+(tb*0.189),tr);
fg=(int)colorBlend(noise(),(tr*0.349)+(tg*0.686)+(tb*0.168),tg);
fb=(int)colorBlend(noise(),(tr*0.272)+(tg*0.534)+(tb*0.131),tb);
outPixs[index]=(ta<<24) | (clamp(fr)<<16) | (clamp(fg)<<8) | clamp(fb);
bitmap.setPixel(cols,rows,outPixs[index]);
}
}
Log.i(TAG, "789**********************");
然后再重新运行:
好了问题就解决了,一行代码之差.
整个app运行效果:
左上角是没有调整的原图,下面是经过处理过的,照片发黄的效果了.
<1> : 新建Android工程如下:
<2> : 工程里面还有其他的代码,这里只给出主要涉及的:
DurianMainActivity.java
package org.durian.duriangaussian;
import android.app.Activity;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
public class DurianMainActivity extends Activity {
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.durian_main);
imageView=(ImageView)findViewById(R.id.image);
imageView.setImageBitmap(BitmapFactory.decodeResource(this.getResources(),R.drawable.ghh));
}
}
DurianGaussView.java
package org.durian.duriangaussian; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.os.AsyncTask; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.View; /** * Created by Administrator on 2016/1/8. */ public class DurianGaussView extends View { private final static String TAG = "DurianGaussView"; private Bitmap mBitmap; private Bitmap mOldPhotoMap; private int mBitmapWidth; private int mBitmapHeight; private int mArrayColorLength; private int mArrayColor[] = null; private int mInColors[] = null; private int mOutColors[] = null; private int count = 0; private Context mContext; public DurianGaussView(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } private void initView(Context context) { mContext=context; mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ghh); mBrightnessBitmap.execute(); mOldPhotoMap= BitmapFactory.decodeResource(context.getResources(), R.drawable.ghh); mOldPhotoEffort.execute(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int index=0; // canvas.drawBitmap(mBitmap,25.0f,25.0f,null); canvas.drawBitmap(mOldPhotoMap,500f,25.0f,null); /*for (int i = 0; i < 100; i++) { int x = i - 50; double y = Gauss.gaussFormula(x / 10); }*/ } private Handler mHandler=new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.i(TAG,"message what : " +msg.what); invalidate(); } }; private OldPhotoEffort mOldPhotoEffort=new OldPhotoEffort(); private class OldPhotoEffort extends AsyncTask<String,Integer,String>{ @Override protected String doInBackground(String... params) { Log.i(TAG,"OldPhotoEffort : ..."); mOldPhotoMap=DurianOldPhotoEffort.makeOldPhotoEffort(mContext); mHandler.sendEmptyMessage(100); return null; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected void onPostExecute(String s) { super.onPostExecute(s); } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); } } private BrightnessBitmap mBrightnessBitmap=new BrightnessBitmap(); private class BrightnessBitmap extends AsyncTask<String,Integer,String>{ @Override protected String doInBackground(String... params) { // mBitmap=DurianBrightness.decodeBitmap(mContext); mHandler.sendEmptyMessage(0); return null; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected void onPostExecute(String s) { super.onPostExecute(s); } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); } } }
上面有两个工作线程,这里屏蔽其中一个功能.
DurianOldPhotoEffort.java
package org.durian.duriangaussian;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
/**
* Created by Administrator on 2016/1/13.
*/
public class DurianOldPhotoEffort {
private final static String TAG="DurianOldPhotoEffort";
public static Bitmap makeOldPhotoEffort(Context context){
Bitmap bitmap= BitmapFactory.decodeResource(context.getResources(),R.drawable.ghh);
int bitmapWidth=bitmap.getWidth();
int bitmapHeight=bitmap.getHeight();
int pixLength=bitmapHeight*bitmapWidth;
int inPixs[]=new int[pixLength];
int outPixs[]=new int[pixLength];
int tr=0,tg=0,tb=0,ta=0;
int index=0;
int color=0;
Log.i(TAG, "123**********************");
for (int row=0;row<bitmapHeight;row++){
for (int col=0;col<bitmapWidth;col++){
index=row*bitmapWidth+col;
color=bitmap.getPixel(col,row);
inPixs[index]=color;
}
}
Log.i(TAG, "456**********************");
int fr=0,fg=0,fb=0;
int rows=0,cols=0;
for (rows=0;rows<bitmapHeight;rows++){
tr=0;tg=0;tb=0;ta=0;
for (cols=0;cols<bitmapWidth;cols++){
index=rows*bitmapWidth+cols;
ta=(inPixs[index]>>24) & 0xFF;
tr=(inPixs[index]>>16) & 0xFF;
tg=(inPixs[index]>>8) & 0xFF;
tb=(inPixs[index]) & 0xFF;
//
/*int fr=(int)colorBlend(noise(),(tr*0.393)+(tg*0.769)+(tb*0.189),tr);
int fg=(int)colorBlend(noise(),(tr*0.349)+(tg*0.686)+(tb*0.168),tg);
int fb=(int)colorBlend(noise(),(tr*0.272)+(tg*0.534)+(tb*0.131),tb);*/
fr=(int)colorBlend(noise(),(tr*0.393)+(tg*0.769)+(tb*0.189),tr);
fg=(int)colorBlend(noise(),(tr*0.349)+(tg*0.686)+(tb*0.168),tg);
fb=(int)colorBlend(noise(),(tr*0.272)+(tg*0.534)+(tb*0.131),tb);
outPixs[index]=(ta<<24) | (clamp(fr)<<16) | (clamp(fg)<<8) | clamp(fb);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
bitmap.setPixel(cols,rows,outPixs[index]);
}
}
Log.i(TAG, "789**********************");
return bitmap;
};
private static double noise(){
return Math.random()*0.5+0.5;
}
private static double colorBlend(double scale,double dest,double src){
return (scale*dest+(1.0-scale)*src);
}
private static int clamp(int c){
return c>255?255:((c<0)?0:c);
}
public String toString(){
return "Effect from Photoshop App !";
}
}
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <org.durian.duriangaussian.DurianGaussView android:id="@+id/durianview" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
里面用到的图片:
<3> : 运行的结果,图片将不会被处理,控制台一直报:
01-14 00:45:27.745 15021-15036/org.durian.duriangaussian I/art﹕ Background partial concurrent mark sweep GC freed 30(1200B) AllocSpace objects, 11(24MB) LOS objects, 33% free, 32MB/48MB, paused 6.652ms total 35.034ms
<4> : 内存图:
右上角的Free和Allocated 旁边内存量大小将不断的变化,从上面的图形来看,内存抖动的非常厉害.
<5> : 解决上面的内存抖动,首先想到的是可能是下面导致的:
//用注释部分的,将会导致内存疯狂抖动 /*int fr=(int)colorBlend(noise(),(tr*0.393)+(tg*0.769)+(tb*0.189),tr); int fg=(int)colorBlend(noise(),(tr*0.349)+(tg*0.686)+(tb*0.168),tg); int fb=(int)colorBlend(noise(),(tr*0.272)+(tg*0.534)+(tb*0.131),tb);*/ //但是由于下面运算量,还是会疯狂抖动 fr=(int)colorBlend(noise(),(tr*0.393)+(tg*0.769)+(tb*0.189),tr); fg=(int)colorBlend(noise(),(tr*0.349)+(tg*0.686)+(tb*0.168),tg); fb=(int)colorBlend(noise(),(tr*0.272)+(tg*0.534)+(tb*0.131),tb);
所以把这里和相关的代码全部用到fr,fg等地方全部屏蔽掉,但是再次运行的时候发现还是不行.
继续查找:
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
bitmap.setPixel(cols,rows,outPixs[index]);发现这段代码的确有问题,bitmap反复copy,我靠,有点低级错误呀.看来需要把这一句代码放在for循环外面:
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
调整为:
Log.i(TAG, "456**********************");
int fr=0,fg=0,fb=0;
int rows=0,cols=0;
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
for (rows=0;rows<bitmapHeight;rows++){
tr=0;tg=0;tb=0;ta=0;
for (cols=0;cols<bitmapWidth;cols++){
index=rows*bitmapWidth+cols;
ta=(inPixs[index]>>24) & 0xFF;
tr=(inPixs[index]>>16) & 0xFF;
tg=(inPixs[index]>>8) & 0xFF;
tb=(inPixs[index]) & 0xFF;
fr=(int)colorBlend(noise(),(tr*0.393)+(tg*0.769)+(tb*0.189),tr);
fg=(int)colorBlend(noise(),(tr*0.349)+(tg*0.686)+(tb*0.168),tg);
fb=(int)colorBlend(noise(),(tr*0.272)+(tg*0.534)+(tb*0.131),tb);
outPixs[index]=(ta<<24) | (clamp(fr)<<16) | (clamp(fg)<<8) | clamp(fb);
bitmap.setPixel(cols,rows,outPixs[index]);
}
}
Log.i(TAG, "789**********************");
然后再重新运行:
好了问题就解决了,一行代码之差.
整个app运行效果:
左上角是没有调整的原图,下面是经过处理过的,照片发黄的效果了.
相关文章推荐
- SurfaceView 基础用法
- android138 360 小火箭
- Android Studio项目目录结构介绍
- 从TextView源码解析:“android开发中,文字的最难适配”
- Android学习第一章第一节android学习路线图
- android sdk是个啥
- 我用的Android Studio插件
- ant android 打包签名和渠道
- AndroidStudio重启adb
- view爆炸的烟花效果
- Android开发 旋转屏幕导致Activity重建解决方法(转)
- Android 性能测试
- os x下 apk逆向工程利器 AndroidCrackTool for Mac 最新版
- 【Android 5.1.1_r1+Nexus4】Android源码的下载、编译到刷机
- android DiskLruCache看源码并记录思路日志
- Android 带清除功能的输入框控件ClearEditText,仿IOS的输入框
- Android登陆界面实现-支持输入框清楚和震动效果功能
- Android Studio: Plugin with id 'android-library' not found 解决办法
- android:layout_gravity 和android:gravity 区别 -------浅谈
- ArcGIS4Android 1:使用Android Studio进行ArcGIS for Android开发的环境部署-正确版