Android

记一次错误:无法调起微信分享图片

2018-08-30  本文已影响300人  Merbng

场景

由于项目需要,要在预览图片界面添加图片分享功能,需要对纯图片进行分享,所以照旧调用了微信分享的封装方法(WxShareUtil.of().open(true, bitmap);),第一个参数为是否分享到朋友圈,第二个参数为bitmap,因为预览的图片为url,需要先将url转为bitmap,但是,无法吊起微信,因为方法用在别的地方分享图片是没问题的,为什么在这就无法吊起微信了。

原因

打开log查看并没有明显的报错,但发现一条 checkArgs fail, thumbData is invalid,在网上查了一下,说是缩略图太大,微信限制缩略图只能小于32k,打断点查看,确实是缩略图太大。

                msg.thumbData = BitmapUtils.bitmap2Bytes(thumbBmp);
                //压缩缩略图到32kb
                if (msg.thumbData != null && msg.thumbData.length > '耀') {        //微信sdk里面判断的大小
                    msg.thumbData = BitmapUtils.compressBitmap(msg.thumbData, '耀');
                }

暂时解决,但是,因为图片大多为用户相机直接拍照的大图,所以,好多相机直接拍摄的图片仍旧无法吊起微信,提示错误为checkArgs fail, content is too large,查看源码发现是分享的图片过大,所以这里需要进行压缩。

微信分享源码.png
调用代码如下:
    public void open(boolean isChat, Bitmap bmp) {
        if (!iwxapi.isWXAppInstalled()) {
            Toast.makeText(app, "您尚未安装微信客户端", Toast.LENGTH_SHORT).show();
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                WXImageObject imgObj = new WXImageObject();
                Bitmap bitmap = compressScale(bmp);
                imgObj.imageData = bmpToByteArray(bitmap, true);
                WXMediaMessage msg = new WXMediaMessage();
                msg.mediaObject = imgObj;

                Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, 120, 120, true);
                msg.thumbData = BitmapUtils.bitmap2Bytes(thumbBmp);
                //压缩缩略图到32kb
                if (msg.thumbData != null && msg.thumbData.length > '耀') {        //微信sdk里面判断的大小
                    msg.thumbData = BitmapUtils.compressBitmap(msg.thumbData, '耀');
                }
                SendMessageToWX.Req req = new SendMessageToWX.Req();
                req.transaction = buildTransaction("img");
                req.message = msg;
                req.scene = isChat ? SendMessageToWX.Req.WXSceneSession : SendMessageToWX.Req.WXSceneTimeline;
                boolean sendReq = iwxapi.sendReq(req);
            }
        }).start();
    }

bmpToByteArray

    public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, 100, output);
        if (needRecycle) {
            bmp.recycle();
        }

        byte[] result = output.toByteArray();
        try {
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

BitmapUtils.bitmap2Bytes()

    /**
     * Bitmap 转 bytes
     * @param bitmap
     * @return
     */
    public static byte[] bitmap2Bytes(Bitmap bitmap) {
        ByteArrayOutputStream byteArrayOutputStream = null;
        if(bitmap != null && !bitmap.isRecycled()) {
            try {
                byteArrayOutputStream = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
                if(byteArrayOutputStream.toByteArray() == null) {
                    LogUtils.e("BitmapUtils", "bitmap2Bytes byteArrayOutputStream toByteArray=null");
                }
                return byteArrayOutputStream.toByteArray();
            } catch (Exception e) {
                LogUtils.e("BitmapUtils", e.toString());
            } finally {
                if(byteArrayOutputStream != null) {
                    try {
                        byteArrayOutputStream.close();
                    } catch (IOException var14) {
                        ;
                    }
                }
            }

            return null;
        } else {
            LogUtils.e("BitmapUtils", "bitmap2Bytes bitmap == null or bitmap.isRecycled()");
            return null;
        }
    }

compressScale


    /**
     * 图片按比例大小压缩方法
     *
     * @param image (根据Bitmap图片压缩)
     * @return
     */
    public static Bitmap compressScale(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        // 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
        if (baos.toByteArray().length / 1024 > 3072) {
            baos.reset();// 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, 80, baos);// 这里压缩50%,把压缩后的数据存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
//         float hh = 800f;// 这里设置高度为800f
//         float ww = 480f;// 这里设置宽度为480f
        float hh = 512f;
        float ww = 512f;
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) { // 如果高度高的话根据高度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be; // 设置缩放比例
        // newOpts.inPreferredConfig = Config.RGB_565;//降低图片从ARGB888到RGB565
        // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = new ByteArrayInputStream(baos.toByteArray());
        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
//        return bitmap;
    }

    public static Bitmap compressImage(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 90;
        while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset(); // 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
            options -= 10;// 每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        return bitmap;
    }

最后

经测试,图片可吊起微信进行分享,但是图片清晰度降低,上面的压缩是先按比例大小压缩,再按质量压缩,均为有损压缩,目前较为流行的是鲁班的压缩(文件File压缩)。

上一篇 下一篇

猜你喜欢

热点阅读