微信 SDK 分享图片报错“checkArgs fail, thumbData is invalid”解决方案

手头一个项目中需要使用微信 SDK 分享图片,但遇到了有些图片分享没问题有些却无反应的问题,实际抓取日志发现微信 SDK 有打印错误信息,即

checkArgs fail, thumbData is invalid

因为其他图片可以正常分享,那么这句错误的大致意思就是缩略图的大小超出限制所以无效,网上给出的各种方案基本都是尽量压缩图像以适合微信 SDK 的 32k 字节数(实际上是32768)的分享限制,然而基本都是一棒子打死,我在其基础上进行了修改,改为了根据图像逐级减少清晰度直到适合微信 32k 字节数限制后,分享即可正常进行,具体修改后的算法如下:

    private static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
        byte[] data = bmpToByteArray(bmp, 100);
        if (DEBUGMODE) Log.d(">>>", "zipBitmap: quality=100" + "   size=" + data.length);
        int i = 100;
        while (data.length > '耀') {             //请勿问我为啥用 '耀' 这个字,这问题问微信 SDK 开发者去,他就是这么判断的
            if (i > 10) {
                i = i - 10;
            } else {
                i = i - 1;
            }
            if (i <= 0) {
                if (DEBUGMODE)
                    Log.e(">>>", "zipBitmap: 失败,很无奈清晰度已经降为0,但压缩的图像依然不符合微信的要求,最后size=" + data.length);
                break;
            }
            data = bmpToByteArray(bmp, i);
            if (DEBUGMODE) Log.d(">>>", "zipBitmap: quality=" + i + "   size=" + data.length);
        }
        if (needRecycle)
            bmp.recycle();
        return data;
    }
    
    public static byte[] bmpToByteArray(final Bitmap bmp, int quality) {
        int i;
        int j;
        if (bmp.getHeight() > bmp.getWidth()) {
            i = bmp.getWidth();
            j = bmp.getWidth();
        } else {
            i = bmp.getHeight();
            j = bmp.getHeight();
        }
        
        Bitmap localBitmap = Bitmap.createBitmap(i, j, Bitmap.Config.RGB_565);
        Canvas localCanvas = new Canvas(localBitmap);
        
        while (true) {
            localCanvas.drawBitmap(bmp, new Rect(0, 0, i, j), new Rect(0, 0, i, j), null);
            ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();
            localBitmap.compress(Bitmap.CompressFormat.JPEG, quality,
                                 localByteArrayOutputStream
            );
            localBitmap.recycle();
            byte[] arrayOfByte = localByteArrayOutputStream.toByteArray();
            try {
                localByteArrayOutputStream.close();
                return arrayOfByte;
            } catch (Exception e) {
                //F.out(e);
            }
            i = bmp.getHeight();
            j = bmp.getHeight();
        }
    }

主要过程是从 100% 原图开始逐级向下减少清晰度尝试压缩图像至 32k 字节范围内,如果下降到原图 10% 清晰度时依然不满足小于 32k 字节的条件,则以逐级 1% 递减清晰度直至 0% 无法压缩为止。基本满足了大部分图片压缩情况的需要,而且不会对原本就符合要求的图像进行“一棒子打死”式的压缩。

小彩蛋是微信 SDK 中判断 32k 的条件是通过一个字来实现的,即 '耀',这我也与其保持一致。

如果不想这么麻烦直接一步搞定,可以使用我开源的库 # WechatHelper
一并提供了 微信登录、支付、分享的封装,帮你排坑,更轻松的完成微信功能的开发。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容