记一次错误:无法调起微信分享图片
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
,查看源码发现是分享的图片过大,所以这里需要进行压缩。
调用代码如下:
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压缩)。