Android笔记:将布局转换成图片

2022-01-10 14:20:56 浏览数 (2)

如题,需求就是把xml里面的布局转换成图片,然后保存下来,大家觉得特别简单吧,去问过好多人,也查了查很多app都有这么一个功能,当用户完成了app的某个任务时,产品希望用户点击分享的时候,能动态绘制出一张图片,让用户的分享的内容更加生动化

思路不复杂,可是实践起来简直太多坑了。

1:获取布局

代码语言:javascript复制
relativeLayout = (RelativeLayout) findViewById(R.id.layout_rl);

2:设置布局相关设置

代码语言:javascript复制
// 获取图片某布局

relativeLayout.setDrawingCacheEnabled(true);

relativeLayout.buildDrawingCache();

3.获取图片

代码语言:javascript复制
final Bitmap bmp = relativeLayout.getDrawingCache(); // 获取图片

savePicture(bmp, "test.jpg");// 保存图片

4:保存图片

代码语言:javascript复制
public void savePicture(Bitmap bm, String fileName) {

    Log.i("xing", "savePicture: ------------------------");

    if (null == bm) {

      Log.i("xing", "savePicture: ------------------图片为空------");

      return;

    }

    File foder = new File(Environment.getExternalStorageDirectory().getAbsolutePath()   "/test");

    if (!foder.exists()) {

      foder.mkdirs();

    }

    File myCaptureFile = new File(foder, fileName);

    try {

      if (!myCaptureFile.exists()) {

        myCaptureFile.createNewFile();

      }

      BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));

      //压缩保存到本地

      bm.compress(Bitmap.CompressFormat.JPEG, 90, bos);

      bos.flush();

      bos.close();

    } catch (IOException e) {

      e.printStackTrace();

    }

    Toast.makeText(this, "保存成功!", Toast.LENGTH_SHORT).show();


  }

5:释放资源

代码语言:javascript复制
relativeLayout.destroyDrawingCache();

View.getDrawingCache() 只适用于分享的View已经完整展示在用户的屏幕上,还有种情况是需要转化为bitmap的布局没有显示,而需要我们在后台生成btmap,我们只需要获取到屏幕的宽高在view生成图片的时候传进去即可,否则会报空指针的

代码语言:javascript复制
WindowManager manager = this.getWindowManager();
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
int width = outMetrics.widthPixels;
int height = outMetrics.heightPixels;

假设我当前是在A页面,我要分享出去的B图片和A页面只需要隐藏分享按钮,接下来提供第二种方法,这种方法的做法是:

代码语言:javascript复制
Bitmap b = Bitmap.createBitmap( v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888); 
Canvas c = new   Canvas(b); 
v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); 
v.draw(c);
return b;

这里提供一下核心的代码:

代码语言:javascript复制
/** 
* 创建分享的图片文件 
*/
public String createShareFile() {    
    Bitmap bitmap = createBitmap();
    //将生成的Bitmap插入到手机的图片库当中,获取到图片路径
    String filePath = MediaStore.Images.Media.insertImage(getContext().getContentResolver(),     bitmap, null, null);    
    //及时回收Bitmap对象,防止OOM
    if (!bitmap.isRecycled()) {        
        bitmap.recycle();    
    } 
    //转uri之前必须判空,防止保存图片失败
    if (TextUtils.isEmpty(filePath)) {        
        return "";    
    }    
    return getRealPathFromURI(getContext(), Uri.parse(filePath));
}

/** 
* 创建分享Bitmap 
*/
private Bitmap createBitmap() {  
    //自定义ViewGroup,一定要手动调用测量,布局的方法  
    measure(getLayoutParams().width, getLayoutParams().height);    
    layout(0, 0, getMeasuredWidth(), getMeasuredHeight());
    //如果图片对透明度无要求,可以设置为RGB_565
    Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);    
    Canvas canvas = new Canvas(bitmap);    
    draw(canvas);   
    return bitmap;
}

private static String getRealPathFromURI(Context context, Uri contentUri) {
    Cursor cursor = null;    
    try {        
        String[] proj = {MediaStore.Images.Media.DATA};        
        cursor = context.getContentResolver().query(contentUri, proj, null, null, null);       
         if (cursor == null) {            
            return "";        
          }        
         int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();        
        return cursor.getString(column_index);    
    } finally {        
        if (cursor != null) {            
            cursor.close();       
        }    
   }
}

在文章的结尾提醒大家一下网络图片需要加载完成后再回调生成图片成功的方法,例如在Glide的RequestListener等。

马上就要过年了,在这里住大家新年快乐!以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

0 人点赞