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

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

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

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;
}

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

【Android实战】Bitmap图片的截屏、模糊处理、传递、使用的更多相关文章

  1. 【转】Android 音量键+电源键 截屏代码小结

    http://104zz.iteye.com/blog/1752961 原文地址:http://blog.csdn.net/hk_256/article/details/7306590 ,转载请注明出 ...

  2. Android—将Bitmap图片保存到SD卡目录下或者指定目录

    直接上代码就不废话啦 一:保存到SD卡下 File file = new File(Environment.getExternalStorageDirectory(), System.currentT ...

  3. Android adb录制视频和截屏的dos脚本

    以下是本人写的脚本,用于录制android手机视频.截屏 dos脚本文件名:screenrecord.bat @ECHO OFF CLS color 0a set SCREEN_RECORD_SAVE ...

  4. Android 7.1.1 系统截屏

    frameworks/base/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java Tak ...

  5. html转图片网页截屏(二)PhantomJS

    关于PhantomJS PhantomJS 是一个基于WebKit的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS ...

  6. ios 代码截屏模糊问题解决办法

    我们常用的截图方法如下所示: //尺寸是按照 UIGraphicsBeginImageContext(CGSizeMake(, )); //currentView 当前的view 创建一个基于位图的图 ...

  7. android中bitmap图片与二进制,String间的转化

    1, public Bitmap stringtoBitmap(String string) {                 // 将字符串转换成Bitmap类型                 ...

  8. html转图片网页截屏(三),puppeteer

    puppeteer谷歌出品,是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome. 官方github地址:https://github ...

  9. 【转】Android截屏

     http://blog.csdn.net/xww810319/article/details/17607749 Android截屏浅析 链接:http://blog.sina.com.cn/s/bl ...

随机推荐

  1. Mysql-in查询问题

    Mysql-in查询问题 标签(空格分隔): mysql 问题:mysql用in语法查询出来的数据少了好多! 我的实际情况: 数据表: content字段记录着一些选项的id,多个选项用逗号隔开,比如 ...

  2. Win32++:可替代MFC的Windows桌面应用开发框架

    写在前面 有过Win32编程经验的朋友都知道,使用Windows提供的API开发桌面应用是相当繁琐的,创建一个功能简单能接收并处理消息的窗口至少也得几百行代码.创建一个可视化的窗口一般要以下几个步骤: ...

  3. IHttpHandler的学习(0-2)

    这个IHttpHandler,要想到asp.net生命周期 ,想到哪个从你发起请求开始,这个请求通过HttpModule------>IHttpHandler的: 执行HttpModule的一系 ...

  4. BootStrap--panel面板

    1 <div class="panel panel-default"> <div class="panel-body"> 这是一个基本的 ...

  5. 细说ReactiveCocoa的冷信号与热信号(一)

    热信号:事件触发: 冷信号:订阅出发: 从本质上来说,是信号的存在和产生,是静态信号和动态信号的区别. 背景 ReactiveCocoa(简称RAC)是最初由GitHub团队开发的一套基于Cocoa的 ...

  6. BZOJ5017 炸弹(线段树优化建图+Tarjan+拓扑)

    Description 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被 ...

  7. 三种记录 MySQL 所执行过的 SQL 语句的方法

    程式 Debug 有時後從前面第一行追起來很辛苦(程式碼太多或 compile 過), 另一種做法就是從後面追起來, 反正最後寫入的是 DB, 那就從 DB 開始往前推, 所以就是要抓程式是執行哪些 ...

  8. linux中的硬连接和软连接

    linux中的硬连接和软连接 linux中的硬连接和软连接 背景 连接 硬连接 软连接 example reference 背景 linux中的文件主要分3块, - 真正的数据 - 索引节点号(ino ...

  9. android动画-拖动

    先上图看效果 实质上说是动画有点不妥,确切的说应该是手势的处理,废话不多说看代码 SimpleDragSample.java public class SimpleDragSample extends ...

  10. HDU 3555 Bomb(数位DP模板啊两种形式)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 Problem Description The counter-terrorists found ...