Android截屏幕实现,截取屏幕为bitmap,并保存进手机图库,activity之间传递bitmap对象

xiaoxiao2021-02-28  87

Android截屏幕实现,截取超过一屏幕的长图,截取当前显示的一屏幕的图片,截图屏幕内的部分图片,并保存到本地,更新到手机图库中;当然还有一种bitmap在activity之间传递的需求

踩坑—–>很多时候,截屏其实大概率两种需求,第一,保存图片到本地;第二,分享这张图片到qq,wechat等这样的第三方,这里有一个大坑是,截图出来发现是一个黑色的背景,很尴尬,查询资料发现,大概原因是因为,图片的rgb颜色超过系统最大值了,解决方案是调用一个static的方法,傻傻的调用呗,有时候并没有什么作用,出来还是黑色背景哦,其实还是一脸懵逼,我只是简单的截图,怎么还设计到了rgb颜色了呢,我还没做美图效果呢,如果我做了美图秀秀一样的颜色加深,锐化等效果或者做一个高清图的要求,岂不是炸裂?

1,首先,来讨论这个截屏的问题,截屏存在多个情况,

①:截取超过一屏幕的scrollview的图片为bitmap;

②:截取当前手机屏幕展示的布局的图片为bitmap;

③:截取手机屏幕内的一小块布局的图片为bitmap;

这三种实现总的来说是一个思路,但是,在具体实现过程中,其实是有差异的,对于不同的三种要求,用同样的方法,其实会出现无法截出来图,也就是bitmap为空的情况;

下面具体讨论下实现

这种需求是比较容易实现的,可以直接调用系统的获取屏幕的功能

/** * 调用系统截图功能获取屏幕截图 * @return */ private Bitmap getScreenShot(View view) { view = getWindow().getDecorView(); view.setDrawingCacheEnabled(true); view.buildDrawingCache(); return view.getDrawingCache(); }

看到,传入的是一个view对象,确实对这个view截图了,但是,其实结果确是令人尴尬,出来的是当前屏幕展示的整个范围大小的图片,不妨来看看效果图。

这种截图可以截取长图,小图,都是OK的,像素也还比较清晰

// 打开图像缓存 View layout=findviewById(R.id.res); layout.setDrawingCacheEnabled(true); // 获取可视组件的截图 Bitmap cacheBitmap = layout.getDrawingCache(); layout.setDrawingCacheEnabled(false);

这种截图,截取的图,仿佛老年机啊

public static Bitmap convertviewToBitmap(View view){ view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); view.buildDrawingCache(); // Bitmap bitmap=view.getDrawingCache(); Bitmap bitmap=Bitmap.createBitmap(view.getDrawingCache()); return bitmap; }

还有一个布局转bitmap的方式,效果也不错,如果截屏出现了黑色背景,不妨试试这种方式,因为可以设置rgb颜色:

public static Bitmap loadBitmapFromView(View v, boolean isParemt) { if (v == null) { return null; } Bitmap screenshot; int width=v.getWidth(); int height=v.getHeight(); screenshot = Bitmap.createBitmap(width,height ,Config.RGB_565 /*HDConstantSet.BITMAP_QUALITY*/); Canvas c = new Canvas(screenshot); c.translate(-v.getScrollX(), -v.getScrollY()); v.draw(c); return screenshot; }

截图是黑色背景,还可以提供一种思路,画笔–画板,把这个图画在一张白色的画板上试试呗,其实我的开发发现,如果截图的布局外面,特别是scrollview这种高度需要重新计算的布局,紧紧跟在scrollview下面的那个布局如果有一张图片背景,就会出现黑底,给一个rgb颜色background都不会出现黑底。

public static Bitmap drawBg4Bitmap(int color, Bitmap orginBitmap) { Paint paint = new Paint(); paint.setColor(color); Bitmap bitmap = Bitmap.createBitmap(orginBitmap.getWidth(), orginBitmap.getHeight(), orginBitmap.getConfig()); Canvas canvas = new Canvas(bitmap); canvas.drawRect(0, 0, orginBitmap.getWidth(), orginBitmap.getHeight(), paint); canvas.drawBitmap(orginBitmap, 0, 0, paint); if(orginBitmap!=null){ orginBitmap.recycle(); } return bitmap; }

2,讨论下,把bitmap这个截图保存在本地,然后更新到本地的图库中去

public static void saveImageToGallery(Context context, Bitmap bmp) { // 首先保存图片路径 File appDir = new File(Environment.getExternalStorageDirectory(), "xiaoheiqun"); if (!appDir.exists()) { appDir.mkdir(); } //当前时间来命名图片 String fileName = System.currentTimeMillis() + ".jpg"; File file = new File(appDir, fileName); try { FileOutputStream fos = new FileOutputStream(file); bmp.compress(CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 其次把文件插入到系统图库 try { MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName, null); } catch (FileNotFoundException e) { e.printStackTrace(); } // 最后通知图库更新 Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); Uri uri = Uri.fromFile(file); intent.setData(uri); context.sendBroadcast(intent); Toast.makeText(context, "图片保存到本地成功", Toast.LENGTH_SHORT).show(); }

3,讨论下,activity之间传递bitmap对象的问题

实现思路是比较简单的,传递数据基本数据类型,bundle,序列化的Javabean,还没有听说过有直接传递bitmap的,查询也发现好像是不支持直接传递bitmap的,那么另辟蹊径——>把bitmap转为bit数组,然后存入sharePreference,然后在另一个activity中,通过这个sharePreference来获取到这个bitArray,然后把bitArray还原bitmap;

在传递的发起传递的页面 ,resource页面:

/** * 传递图片bitmap */ private void transmitBitmap() { //首先截图图片出来 // 打开图像缓存 meitu_pic.setDrawingCacheEnabled(true); // 获取可视组件的截图 cacheBitmap2 = meitu_pic.getDrawingCache(); //其次,转为输出流,转为字节数组 ByteArrayOutputStream baos = new ByteArrayOutputStream(); cacheBitmap2.compress(CompressFormat.PNG, 50,baos); String imageBase64 = new String (Base64.encode(baos.toByteArray(), 0)); //最后把字节数组存入SharedPreferences SharedPreferences sPreferences = getSharedPreferences("share", Context.MODE_PRIVATE); Editor editor = sPreferences.edit(); editor.putString("image", imageBase64); editor.commit(); meitu_pic.setDrawingCacheEnabled(false); destroyBitmap(cacheBitmap2); } /** * 销毁bitmap,释放空间,防止oom * @param bitmap */ private void destroyBitmap(Bitmap bitmap){ if(bitmap!=null){ bitmap.recycle(); } }

在接收的页面,Destination页面

//展示图片 SharedPreferences sPreferences = getSharedPreferences("share", Context.MODE_PRIVATE); String imageBase64 = sPreferences.getString("image", ""); byte[] byte64 = Base64.decode(imageBase64, 0); ByteArrayInputStream bais = new ByteArrayInputStream(byte64); Bitmap bitmap = BitmapFactory.decodeStream(bais); ImageView share_pic=(ImageView)findViewById(R.id.img); share_pic.setImageBitmap(bitmap); server_info=share_txt.getText().toString(); //使用完,清空这个sharePreference,防止oom server_url=FeedbackEvaCreateMeizhaoActivity.picUrl; sPreferences.edit().clear();
转载请注明原文地址: https://www.6miu.com/read-23406.html

最新回复(0)