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

时间:2022-06-10 01:44:20

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

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

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

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 音量键&plus;电源键 截屏代码小结

    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&period;1&period;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. code force 403B&period;B&period; The Meeting Place Cannot Be Changed

    B. The Meeting Place Cannot Be Changed time limit per test 5 seconds memory limit per test 256 megab ...

  2. JFinal极速开发框架使用笔记&lpar;三&rpar; 分析Model和ActiveRecord

    JFinal框架的一些新发现的用法: 在JFinal框架中,实体类并不需要设置属性,更不需要配置getset方法就可以很方便的操作数据库,如果需要设置或者获取属性,可以直接使用一下方式: User u ...

  3. test for python socket

    server: #!/usr/bin/python import socket import threading import time def tcplink(sock, addr): print ...

  4. Docker普通用户不使用sudo提权

    解决方法 sudo groupadd docker 添加Docker用户组 sudo gpasswd -a ${USER} docker 添加你的用户到Docker用户组 reboot 重启系统.也可 ...

  5. springmvc 怎么响应json数据

    springmvc 怎么响应json数据@Controller@RequestMapping("/items") class ItemsController{  @RequestM ...

  6. eclipse导入Tomcat8源码

    最近这段时间在学习how tomcat works这本书,需要结合书上的例子对照tomcat源码来看,需要导入tomcat的源码,所以在网上找了很多教程,结合自己遇到的问题,记录如下: 1.前期准备 ...

  7. SQL Server 2008中SQL之WaitFor

    SQL Server 2008中SQL应用系列--目录索引 在SQL Server 2005以上版本中,在一个增强的WaitFor命令,其作用可以和一个job相当.但使用更加简捷. 看MSDN: ht ...

  8. Message&colon; u&&num;39&semi;The given selector btn dropdown-toggle btn-info is either invalid or does not result in a WebElement

    html代码: <html> <head> <meta http-equiv="content-type" content="text/ht ...

  9. cocos2d-x动画加速与减速

    动画是游戏的必定要素之中的一个,在整个游戏过程中,又有着加速.减速动画的需求.以塔防为样例,布塔的时候希望可以将游戏减速,布好塔后,则希望能将游戏加速:当某个怪被冰冻后,移动速度减缓,而其它怪的移动速 ...

  10. GreenDao 初体验

    GreenDao 使用 环境搭建(android studio) project的build.gradle buildscript { repositories { google() jcenter( ...