一、杂谈

微信分享图片的迷之bug,前一阵子接盘一个Hybrid App,分享要用原生的分享,搞了一阵子把微信分享搞上,测试又反馈了一个谜一样的Bug,我这边看Log打印了checkArgs fail, thumbData is invalid,google一番都说是图片不能超过32kb,在分享里面看到如下判断this.thumbData.length > '耀',一时间没有反应过来。。。可是怎么压缩好哇,我参照官方Demo和AndroidUtilCode的按质量压缩方法,找出了下面的解决方案,供大家参考。

二、将网络图片加载到内存

保存到本地在操作真心感觉麻烦

  1. public static byte[] getHtmlByteArray(final String url) {
  2. URL htmlUrl = null;
  3. InputStream inStream = null;
  4. try {
  5. htmlUrl = new URL(url);
  6. URLConnection connection = htmlUrl.openConnection();
  7. HttpURLConnection httpConnection = (HttpURLConnection) connection;
  8. int responseCode = httpConnection.getResponseCode();
  9. if (responseCode == HttpURLConnection.HTTP_OK) {
  10. inStream = httpConnection.getInputStream();
  11. }
  12. } catch (MalformedURLException e) {
  13. e.printStackTrace();
  14. } catch (IOException e) {
  15. e.printStackTrace();
  16. }
  17. // 将io流转为byte数组
  18. byte[] data = inputStreamToByte(inStream);
  19. if (data.length > '耀') {
  20. // 转换为bitmap
  21. Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
  22. // 获取压缩后的byte数组
  23. data = compressByQuality(bitmap, '耀', true);
  24. }
  25. return data;
  26. }

三、将io流转为byte数组

  1. public static byte[] inputStreamToByte(InputStream is) {
  2. try {
  3. ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
  4. int ch;
  5. while ((ch = is.read()) != -1) {
  6. bytestream.write(ch);
  7. }
  8. byte imgdata[] = bytestream.toByteArray();
  9. bytestream.close();
  10. return imgdata;
  11. } catch (Exception e) {
  12. e.printStackTrace();
  13. }
  14. return null;
  15. }

四、按质量压缩

  1. /**
  2. * 按质量压缩图片
  3. *
  4. * @param src bitmap图片
  5. * @param maxByteSize 最大字节数
  6. * @param recycle
  7. * @return
  8. */
  9. public static byte[] compressByQuality(final Bitmap src, final long maxByteSize, final boolean recycle) {
  10. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  11. src.compress(CompressFormat.JPEG, 100, baos);
  12. byte[] bytes;
  13. if (baos.size() <= maxByteSize) {
  14. bytes = baos.toByteArray();
  15. } else {
  16. baos.reset();
  17. src.compress(CompressFormat.JPEG, 0, baos);
  18. if (baos.size() >= maxByteSize) {
  19. bytes = baos.toByteArray();
  20. } else {
  21. // find the best quality using binary search
  22. int st = 0;
  23. int end = 100;
  24. int mid = 0;
  25. while (st < end) {
  26. mid = (st + end) / 2;
  27. baos.reset();
  28. src.compress(CompressFormat.JPEG, mid, baos);
  29. int len = baos.size();
  30. if (len == maxByteSize) {
  31. break;
  32. } else if (len > maxByteSize) {
  33. end = mid - 1;
  34. } else {
  35. st = mid + 1;
  36. }
  37. }
  38. if (end == mid - 1) {
  39. baos.reset();
  40. src.compress(CompressFormat.JPEG, st, baos);
  41. }
  42. bytes = baos.toByteArray();
  43. }
  44. }
  45. if (recycle && !src.isRecycled()) src.recycle();
  46. return bytes;
  47. }

五、微信分享

  1. WXWebpageObject object = new WXWebpageObject();
  2. object.webpageUrl = url;
  3. WXMediaMessage wxMediaMessage = new WXMediaMessage(object);
  4. // 标题
  5. wxMediaMessage.title = title;
  6. // 描述
  7. wxMediaMessage.description = des.substring(0, 20);
  8. // 图片
  9. wxMediaMessage.thumbData = Util.getHtmlByteArray(image);
  10. //构造一个Req
  11. SendMessageToWX.Req req = new SendMessageToWX.Req();
  12. req.transaction = String.valueOf(System.currentTimeMillis());
  13. req.message = wxMediaMessage;
  14. req.scene = SendMessageToWX.Req.WXSceneSession;
  15. mIWXAPI.sendReq(req);

六、源码

WechatShareUtil

https://github.com/sdwfqin/AndroidQuick