zoukankan      html  css  js  c++  java
  • 微信分享大图遇到的问题(Android)

    起因:

    要做一个微信图片分享的功能,但是对于大图会如下问题:

    当时没有仔细查看错误日志,单纯的以为是图片太大的问题。

    分享图片代码:

     1 public void WXsharePic(String transaction, final boolean isSession, Bitmap bitmap) {
     2     //初始化WXImageObject和WXMediaMessage对象
     3     WXImageObject imageObject = new WXImageObject(bitmap);
     4     WXMediaMessage msg = new WXMediaMessage();
     5     msg.mediaObject = imageObject;
     6     //设置缩略图
     7     Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
     8     bitmap.recycle();
     9     msg.thumbData = getBitmapByte(scaledBitmap);
    10     //构造一个Req
    11     SendMessageToWX.Req req = new SendMessageToWX.Req();
    12     req.transaction = transaction + Long.toString(System.currentTimeMillis());
    13     req.message = msg;
    14     //表示发送给朋友圈  WXSceneTimeline  表示发送给朋友  WXSceneSession
    15     req.scene = isSession ? SendMessageToWX.Req.WXSceneSession : SendMessageToWX.Req.WXSceneTimeline;
    16     //调用api接口发送数据到微信
    17     api.sendReq(req);
    18 }

    解决过程:

    想法一:

    查看微信的文档,发现如下信息:

    初步判定是略缩图过大导致的,准备对略缩图进一步压缩。

    但是在调试过程中发现略缩图并没有超过32K,于是这种想法不正确

    想法二:

    既然不是略缩图过大,那大概率就是原图过大了。然而微信官方文档上也没有说明原图大小限制,所以也不知道是否是这个原因。

    于是准备测试一下是否是这个原因,对原图进一步压缩。

     1 public static byte[] bitmap2Bytes(Bitmap bitmap, int maxkb) {
     2     ByteArrayOutputStream output = new ByteArrayOutputStream();
     3     bitmap.compress(Bitmap.CompressFormat.PNG, 100, output);
     4     int options = 100;
     5     while (output.toByteArray().length > maxkb&& options != 10) {
     6         output.reset(); //清空output
     7         bitmap.compress(Bitmap.CompressFormat.JPEG, options, output);//这里压缩options%,把压缩后的数据存放到output中
     8         options -= 10;
     9     }
    10     return output.toByteArray();
    11 }

    从代码可知,设置了一个最大kb值,并每次循环压缩率递减10%.

    然而实际运行中发现无论maxkb设置的多小,还是会出这个问题。

    仔细调试发现,原图大小为3M多,即使是最小10%的压缩率也过大了。

    于是将压缩率递减改为1%.

    将压缩率递减改为1%,并且maxkb设置为500KB时,就没问题了!

    但是,有两个很严重的问题:

    1.微信的原图最大只能是500KB吗?

    2.循环压缩所需时间太久,差不多半分钟才能压缩完毕,效率太低。

    想法三:

    这个时候,我才开始注意起错误日志来。

    错误日志是Binder类出现的,字面意思是数据过大。查看微信的SDK源码可以发现实际上调用微信API,微信会将图片传递给一个新的活动。

    Intent传值有大小限制,最大只能512KB

    现在错误原因知道了,微信分享图片会涉及到启动一个新活动,而新活动涉及到Intent传值,而Intent传值有大小限制,于是就会出问题。

    可是如何解决呢?

    既然直接传图片的Bitmap太大,那就把图片先保存在本地,然后直接传递图片的地址。

    解决过程:

    分享图片:

     1 public void WXsharePic(String transaction, final boolean isSession, Bitmap bitmap, String path) {
     2     //初始化WXImageObject和WXMediaMessage对象
     3     WXImageObject imageObject;
     4     if (!StringUtil.isBlank(path)) {
     5         imageObject = new WXImageObject();
     6         imageObject.setImagePath(path);
     7     } else {
     8         imageObject = new WXImageObject(bitmap);
     9     }
    10     WXMediaMessage msg = new WXMediaMessage();
    11     msg.mediaObject = imageObject;
    12     //设置缩略图
    13     Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
    14     bitmap.recycle();
    15     msg.thumbData = getBitmapByte(scaledBitmap);
    16     //构造一个Req
    17     SendMessageToWX.Req req = new SendMessageToWX.Req();
    18     req.transaction = transaction + Long.toString(System.currentTimeMillis());
    19     req.message = msg;
    20     //表示发送给朋友圈  WXSceneTimeline  表示发送给朋友  WXSceneSession
    21     req.scene = isSession ? SendMessageToWX.Req.WXSceneSession : SendMessageToWX.Req.WXSceneTimeline;
    22     //调用api接口发送数据到微信
    23     api.sendReq(req);
    24 }

    调用分享:

     1 private void shareToMoment() {
     2     final Bitmap sharePicture = getBitmapByView(svShare);
     3     AndPermission.with(this)
     4             .permission(Permission.WRITE_EXTERNAL_STORAGE)
     5             .onGranted(new Action() {
     6                 @Override
     7                 public void onAction(List<String> permissions) {
     8                     String path = saveImageToGallery(sharePicture);
     9                     WXsharePic("he" + System.currentTimeMillis(), true, sharePicture, path);
    10                 }
    11             })
    12             .onDenied(new Action() {
    13                 @Override
    14                 public void onAction(@NonNull List<String> permissions) {
    15                     Log.e("Activity", "权限申请失败");
    16                 }
    17             })
    18             .start();
    19 }

    保存图片:

     1  public String saveImageToGallery(Bitmap bmp) {
     2      // 首先保存图片
     3      String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "dearxy";
     4      File appDir = new File(storePath);
     5      if (!appDir.exists()) {
     6          appDir.mkdir();
     7      }
     8      String fileName = System.currentTimeMillis() + ".jpg";
     9      File file = new File(appDir, fileName);
    10      try {
    11          FileOutputStream fos = new FileOutputStream(file);
    12          //通过io流的方式来压缩保存图片
    13          bmp.compress(Bitmap.CompressFormat.JPEG, 60, fos);
    14          fos.flush();
    15          fos.close();
    16      } catch (IOException e) {
    17          e.printStackTrace();
    18      }
    19      return storePath + "/" + fileName;
    20  }

    反思:

    1. 遇到问题直接查看错误日志,找到问题的根源,不能想当然;
    2. 对于安卓基础的了解有待加强;
    3. 总算明白了为什么QQ分享需要请求存储权限;
    4. BAT现在是大家,对于他们的API需要熟悉了解。

    大家如果有什么疑问或者建议可以通过评论或者邮件的方式联系我,欢迎大家的评论~

  • 相关阅读:
    LA 3882
    Codeforces 161D
    spoj PARTIT
    uva 10496 Collecting Beepers
    uva 10130 SuperSale
    spoj 3885
    NWERC 2012 Problem I Idol
    NWERC 2012 Problem E Edge Case
    【USACO 1.3.2】修理牛棚
    【USACO 1.3.1】混合牛奶
  • 原文地址:https://www.cnblogs.com/lanxingren/p/9669036.html
Copyright © 2011-2022 走看看