Android新姿势:截屏代码整理

今天做项目要用到android截屏功能,一开始我还庆幸看过一些博客的文章,自信能轻松解决。。。- - 结果坑了一天才搞了个差不多的交差。。。哎!

关于android截屏的代码,大致有3种方法,有兴趣的看下去吧。

方法一:

网上看了很多文章,大多用的是这样的方法,直接把一个View转换成Bitmap,然后保存到sd卡。

/**

* 根据view来生成bitmap图片,可用于截图功能

*/

public static Bitmap getViewBitmap(View v) {

v.clearFocus(); //

v.setPressed(false); //

// 能画缓存就返回false

boolean willNotCache = v.willNotCacheDrawing();

v.setWillNotCacheDrawing(false);

int color = v.getDrawingCacheBackgroundColor();

v.setDrawingCacheBackgroundColor(0);

if (color != 0) {

v.destroyDrawingCache();

}

v.buildDrawingCache();

Bitmap cacheBitmap = v.getDrawingCache();

if (cacheBitmap == null) {

return null;

}

Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);

// Restore the view

v.destroyDrawingCache();

v.setWillNotCacheDrawing(willNotCache);

v.setDrawingCacheBackgroundColor(color);

return bitmap;

}

/**

* 保存Bitmap图片为本地文件

*/

public static void saveFile(Bitmap bitmap, String filename) {

FileOutputStream fileOutputStream = null;

try {

fileOutputStream = new FileOutputStream(filename);

if (fileOutputStream != null) {

bitmap.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);

fileOutputStream.flush();

fileOutputStream.close();

}

} catch (FileNotFoundException e) {

L.d("Exception:FileNotFoundException");

e.printStackTrace();

} catch (IOException e) {

L.d("IOException:IOException");

e.printStackTrace();

}

}

这个方法用起来很简单,saveFile(getViewBitmap(view),filename);一句代码就搞定了。

不过在项目里用上之后坑爹的发现WebView截不了图!!QAQ 好吧,只好无奈的到处找资料。

翻遍百度谷歌找到了这样的代码:

/**

* 截取webView可视区域的截图

* @param webView 前提:WebView要设置webView.setDrawingCacheEnabled(true);

* @return

*/

public static Bitmap captureWebViewVisibleSize(WebView webView) {

Bitmap bmp = webView.getDrawingCache();

return bmp;

}

/**

* 截取webView快照(webView加载的整个内容的大小)

* @param webView

* @return

*/

public static Bitmap captureWebView(WebView webView) {

Picture snapShot = webView.capturePicture();

Bitmap bmp = Bitmap.createBitmap(snapShot.getWidth(),

snapShot.getHeight(), Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(bmp);

snapShot.draw(canvas);

return bmp;

}

不过还是解决不了我的问题,原因我想应该是我的webview是用了anychart的js文件和swf文件来生成图表的,网上也找到一些人情况跟我一样,说是用了swf的网页不能截图。

方法二:

截取当前Activity的视图并保存。这个可以说比方法一更简单,只是不够灵活,因为截的图是整个屏幕,可是我又不要状态栏和标题栏。QAQ

不过如果成功的话,可以把截的图裁剪一下取出自己需要的部分,也是没问题的。可惜这个方法也不能截出WebView的动态图表。

代码给出如下:

/**

* 截屏

* @param activity

* @return

*/

public static Bitmap captureScreen(Activity activity) {

activity.getWindow().getDecorView().setDrawingCacheEnabled(true);

Bitmap bmp=getWindow().getDecorView().getDrawingCache();

return bmp;

}

其实这个方法也算是方法一的延伸,都是用到View的getDrawingCache()方法来获取Bitmap,所以不行也是理所当然的。

方法三:

第三种方法是用FrameBuffer实现的截屏,这才是真正意义上的截图!(哎,加班了1个小时,终于让我找到些眉目了!)

先介绍下FrameBuffer:framebuffer是linux内核对显示的最底层驱动。在一般的linux文件系统中,通过/dev/fb0设备文件来提供给应用程序对framebuffer进行读写的访问。这里,如果有多个显示设备,就将依次出现fb1,fb2,…等文件。而在我们所说的android系统中,这个设备文件被放在了/dev/graphics/fb0,而且往往只有这一个。

(你看懂了吗?反正我看不懂。。。)

至于详细的原理有兴趣的可以去百度“FrameBuffer中获取Android屏幕截图”

下面说我整理的代码,经测试在我的手机上是可以成功截图的,使用了anychart的webview也能截下来。

/**

* 截屏

* @param activity

* @return

*/

public static Bitmap captureScreen(Activity activity) {

// 获取屏幕大小:

DisplayMetrics metrics = new DisplayMetrics();

WindowManager WM = (WindowManager) activity

.getSystemService(Context.WINDOW_SERVICE);

Display display = WM.getDefaultDisplay();

display.getMetrics(metrics);

int height = metrics.heightPixels; // 屏幕高

int width = metrics.widthPixels; // 屏幕的宽

// 获取显示方式

int pixelformat = display.getPixelFormat();

PixelFormat localPixelFormat1 = new PixelFormat();

PixelFormat.getPixelFormatInfo(pixelformat, localPixelFormat1);

int deepth = localPixelFormat1.bytesPerPixel;// 位深

byte[] piex = new byte[height * width * deepth];

try {

Runtime.getRuntime().exec(

new String[] { "/system/bin/su", "-c",

"chmod 777 /dev/graphics/fb0" });

} catch (IOException e) {

e.printStackTrace();

}

try {

// 获取fb0数据输入流

InputStream stream = new FileInputStream(new File(

"/dev/graphics/fb0"));

DataInputStream dStream = new DataInputStream(stream);

dStream.readFully(piex);

} catch (Exception e) {

e.printStackTrace();

}

// 保存图片

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

for (int m = 0; m < colors.length; m++) {

int r = (piex[m * 4] & 0xFF);

int g = (piex[m * 4 + 1] & 0xFF);

int b = (piex[m * 4 + 2] & 0xFF);

int a = (piex[m * 4 + 3] & 0xFF);

colors[m] = (a << 24) + (r << 16) + (g << 8) + b;

}

// piex生成Bitmap

Bitmap bitmap = Bitmap.createBitmap(colors, width, height,

Bitmap.Config.ARGB_8888);

return bitmap;

}

记得在AndroidManifest.xml加上两行权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />

还有需要注意的是,手机需要root权限,没root过的手机我还没试过,但估计是不行的。

所以搞了大半天,还是不满意!又不是每个人的手机都有root权限。。。QAQ 但也已经尽力了,先这样吧!之后会改进的~

时间: 2024-08-09 21:56:20

Android新姿势:截屏代码整理的相关文章

ios截屏代码[转]

http://www.cnblogs.com/chenxiangxi/p/3547974.html 这位博主的连接中将ios自定义大小位置的截屏代码写的很不错,马上就能用的方法,对于只想马上用的程序员很有帮助 http://www.2cto.com/kf/201310/250228.html 我将其改为以下代码: 1 #pragma mark -=====自定义截屏位置大小的逻辑代码=====- 2 static int ScreenshotIndex=0; //这里的逻辑直接采用上面博主的逻辑

c# 截屏代码

//方法一 public static void GetScreen1() { //截取屏幕内容 Size screen = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Bitmap memoryImage = new Bitmap(screen.Width, screen.Height); Graphics memoryGraphics = Graphics.FromImage

Android自己定义截屏功能,相似QQ截屏

由于公司业务需求 须要对一个屏幕进行截屏.但自带的截屏功能是远远不够项目的功能需求 ,我们是做一个画板软件 .须要的像QQ那样截屏之后 ,能够看到我们自己定义的工具.有画笔,button等等 .android自带的功能非常easy,仅仅须要Intent隐式调用就全然足够了.但他是系统的应用 ,界面固定.无法定制改动.实现方法跟办法有非常多种,以下记录下我实现的方法 .我是这样一个思路 ,重写一个View组件 ,在OnDraw里面仅仅负责不绘图形(包含半透明的四个矩形,亮框矩形,亮框上的四个小圆点

Qt on Android:应用截屏

在桌面平台上,QScreen::grabWindow 可以为你的应用截屏,Android 平台上这个不管用了,不过有替代方法. 分两种情况来说吧, Qt Widgets 与 Qt Quick. 插播广告,欢迎关注我的微信订阅号"程序视界",扫描下方二维码即可: 程序视界每周更新一到二篇程序员相关的文章,从心出发,漫谈程序员眼中的世界和世界眼中的程序员. Qt Widgets 最关键的就是一个函数: QWidget::render ,这个方法可以把一个 QWidget(包含它的孩子们)的

Android快照与截屏

android WebView的快照和截屏网上介绍的已经很多,在这里简单的记录下: 1.快照,一般我们在使用WebView时,网页放大,有一部分不会再屏幕上显示,如果我们想截取整个WebView的显示部分,我们就可以用的这个,代码如下: /** * 快照 * * @param context * @return */ private Bitmap captureScreen(Activity context) { //View snapShot = context.getWindow().get

iOS截屏代码

/** *截图功能 */ -(void)screenShot{ UIGraphicsBeginImageContextWithOptions(CGSizeMake(640, 960), YES, 0); //设置截屏大小 [[self.view layer] renderInContext:UIGraphicsGetCurrentContext()]; UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); UIGrap

如何使用命令对Android系统进行截屏

Android截图 1.简介 本文是实现对于Android系统在电鱼SAIL-IMX6Q开发板中的截屏命令的使用. 2.准备 SAIL-IMX6Q开发板利用232串口连接电脑,并连接上电源. 再通过连接OTG线,连接电脑,进行安卓系统的烧录. 在电脑端打开超级终端并完成基础设置(波特率:115200,数据位:8,奇偶校验:无,停止位:1,数据流控制:硬件),之后打开开发板电源. 3.解除休眠 烧录安卓系统到开发板i.MX6Q中 开发板连接PC,再在PC中打开超级终端配置成功后开启开发板电源 开机

ios摇一摇截屏代码

#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //1.添加一个视图 UIView *greenView=[[UIView alloc]init]; greenView.frame=CGRectMake(100, 100, 100, 100); greenView.b

Android新姿势:如何截取短信

公司要做一个[因为是机密所以不能说]的项目,有个需求是拦截手机系统的短信,而且不能在手机的短信应用上显示. OK,一开始以为不难,网上查了一下资料也发现有人做过,于是就开始写demo,结果才发现,这尼玛就是个大坑啊!! 首先网上查到的最多的实现方案是利用自定义的 BroadcastReceiver 去拦截"android.provider.Telephony.SMS_RECEIVED" 的广播,看起来也不难,于是试了下.发现好坑爹啊!在我的酷派大神上无论怎么样就是拦截不到~ 好吧,一定