android bitmap 模糊,【Android实战】Bitmap图片的截屏、模糊处理、传递、使用

项目中遇到了这样一个需求:

当某个条件满足时就截取当前屏幕。并跳转到另外一个页面,同一时候将这个截屏图片作为下一个页面的背景图片,同一时候背景图片须要模糊处理

接下来就一步一步解决这个问题:

1、截取无状态栏的当前屏幕图片。请參考takeScreenShot方法

2、使图片高斯模糊的方法请參考blurBitmap方法

注意:RenderScript是Android在API 11之后增加的,用于高效的图片处理,包含模糊、混合、矩阵卷积计算等

public class ScreenShotUtil {

// 获取指定Activity的截屏,保存到png文件

String filenameTemp = "/mnt/sdcard/temp";

/**

* takeScreenShot:

* TODO 截屏 去掉标题栏

* @param activity

*/

public static Bitmap takeScreenShot(Activity activity) {

// View是你须要截图的View

View view = activity.getWindow().getDecorView();

view.setDrawingCacheEnabled(true);

view.buildDrawingCache();

Bitmap b1 = view.getDrawingCache();

// 获取状态栏高度

Rect frame = new Rect();

activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);

int statusBarHeight = frame.top;

LogHelper.i("TAG", "" + statusBarHeight);

// 获取屏幕长和高

int width = activity.getWindowManager().getDefaultDisplay().getWidth();

int height = activity.getWindowManager().getDefaultDisplay().getHeight();

// 去掉标题栏

// Bitmap b = Bitmap.createBitmap(b1, 0, 25, 320, 455);

Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height - statusBarHeight);

view.destroyDrawingCache();

return b;

}

/**

* TODO 用于高效的图片处理,包含模糊、混合、矩阵卷积计算等

* @param bitmap

* @param context

*/

@SuppressLint("NewApi")

public static Bitmap blurBitmap(Bitmap bitmap, Context context) {

// Let's create an empty bitmap with the same size of the bitmap we want

// to blur

Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),

Config.ARGB_8888);

// Instantiate a new Renderscript

RenderScript rs = RenderScript.create(context);//RenderScript是Android在API 11之后增加的

// Create an Intrinsic Blur Script using the Renderscript

ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));

// Create the Allocations (in/out) with the Renderscript and the in/out

// bitmaps

Allocation allIn = Allocation.createFromBitmap(rs, bitmap);

Allocation allOut = Allocation.createFromBitmap(rs, outBitmap);

// Set the radius of the blur

blurScript.setRadius(25.f);

// Perform the Renderscript

blurScript.setInput(allIn);

blurScript.forEach(allOut);

// Copy the final bitmap created by the out Allocation to the outBitmap

allOut.copyTo(outBitmap);

// recycle the original bitmap

bitmap.recycle();

// After finishing everything, we destroy the Renderscript.

rs.destroy();

return outBitmap;

}

}

3、传递bitmap

刚開始我是这么传递的

bundle.putParcelable("bitmap", ScreenShotUtil.takeScreenShot(theLayout.getActivity()));

继续以下操作:就是将bitmap封装到bundle中,然后封装到intent中启动下一个Activity

ActivityUtil.startActivity(theLayout.getActivity(), LiveEndActivity.class, bundle, false);

/**

* 开启另外一个activity

*

* @param activity

* @param cls 另外的activity类

* @param bundle 传递的bundle对象

* @param isFinish true表示要关闭activity false表示不要关闭activity

*/

public static void startActivity(Activity activity, Class> cls, Bundle bundle, boolean isFinish) {

Intent intent = new Intent(activity, cls);

if (bundle != null) {

intent.putExtras(bundle);

}

activity.startActivity(intent);

if (isFinish) {

activity.finish();

}

activity.overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);

}

然后在LiveEndActivity中这么解析Bitmap bitmap = intent.getExtras().getParcelable("bitmap");

结果:无法得到预期效果

关键是不报错。debug的时候能够看到我们的确截屏成功,可是Bitmap对象就是没有传递过去,并且不是启动下一个Activity

然后去网上找方法调研

结论:不能直接传递大于40k的图片

解决的方法:把bitmap存储为byte数组,然后再继续传递

Bitmap bitmap = ScreenShotUtil.takeScreenShot(theLayout.getActivity());

ByteArrayOutputStream baos=new ByteArrayOutputStream();

bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);

byte [] bitmapByte =baos.toByteArray();

bundle.putByteArray("bitmap", bitmapByte);

// bundle.putParcelable("bitmap", ScreenShotUtil.takeScreenShot(theLayout.getActivity()));

ActivityUtil.startActivity(theLayout.getActivity(), LiveEndActivity.class, bundle, false);

然后在下一个Activity中这么解析

byte[] bis =intent.getExtras().getByteArray("bitmap");

Bitmap bitmap=BitmapFactory.decodeByteArray(bis, 0, bis.length);

4、假如我们须要将这张图片设置为我们当前Activity的背景图片。我们能够这么做

if (bitmap != null) {

bitmap = ScreenShotUtil.blurBitmap(bitmap,getApplicationContext());//高斯模糊处理

getWindow().getDecorView().setBackgroundDrawable(new BitmapDrawable(bitmap));

}

问题基本攻克了。认为实用的能够參考一下!

更新补充:

2015.08.23

* blurBitmap方法在4.2及以上的版本号就能够轻松出效果了。可是在低版本号就会出异常:

* java.lang.NoClassDefFoundError: android.renderscript.ScriptIntrinsicBlur。

* 解决方法:详见http://blog.csdn.net/yangxin_540/article/details/47207727

* 可是我在使用该解决方法时easy出现其他so库 native方法异常的问题

所以找到了第二种方法

/**

* blurImageAmeliorate:模糊效果

* http://blog.csdn.net/sjf0115/article/details/7266998

* @param bmp

* @return

*/

public static Bitmap blurImageAmeliorate(Bitmap bmp)

{

long start = System.currentTimeMillis();

// 高斯矩阵

int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 };

int width = bmp.getWidth();

int height = bmp.getHeight();

Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);

int pixR = 0;

int pixG = 0;

int pixB = 0;

int pixColor = 0;

int newR = 0;

int newG = 0;

int newB = 0;

int delta = 75; // 值越小图片会越亮,越大则越暗

int idx = 0;

int[] pixels = new int[width * height];

bmp.getPixels(pixels, 0, width, 0, 0, width, height);

for (int i = 1, length = height - 1; i < length; i++)

{

for (int k = 1, len = width - 1; k < len; k++)

{

idx = 0;

for (int m = -1; m <= 1; m++)

{

for (int n = -1; n <= 1; n++)

{

pixColor = pixels[(i + m) * width + k + n];

pixR = Color.red(pixColor);

pixG = Color.green(pixColor);

pixB = Color.blue(pixColor);

newR = newR + (int) (pixR * gauss[idx]);

newG = newG + (int) (pixG * gauss[idx]);

newB = newB + (int) (pixB * gauss[idx]);

idx++;

}

}

newR /= delta;

newG /= delta;

newB /= delta;

newR = Math.min(255, Math.max(0, newR));

newG = Math.min(255, Math.max(0, newG));

newB = Math.min(255, Math.max(0, newB));

pixels[i * width + k] = Color.argb(255, newR, newG, newB);

newR = 0;

newG = 0;

newB = 0;

}

}

bitmap.setPixels(pixels, 0, width, 0, 0, width, height);

long end = System.currentTimeMillis();

return bitmap;

}

以下假设还有什么问题。我会继续更新!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值