Android分享微信小程序的图片优化

微信规定,分享小程序展示的图片应该在 128KB 以内,同时图片默认展示比例为 5:4。
所以需要对传入的图片进行裁剪和压缩。关于图片压缩有个很大的坑,改了一晚上才好,所以记录一下,先填坑以后再优化。

参考了其他大神的博客,整理出了下面具体的实现方法:
方法一:

/**
 * 按5:4裁切图片
 */
private static Bitmap cropImage5To4(Bitmap srcBitmap) {
    if (srcBitmap == null) {
        return null;
    }

    int w = srcBitmap.getWidth(); // 得到图片的宽,高
    int h = srcBitmap.getHeight();

    float srcW = w > h * 1.25f ? h * 1.25f : w;
    float srcH = w > h * 1.25f ? h : w / 1.25f;

    float retX = w > h * 1.25f ? (w - h * 1.25f) / 2 : 0;//居中裁剪
    float retY = w > h * 1.25f ? 0 : (h - w / 1.25f) / 2f;

    //以下这句是关键
    return Bitmap.createBitmap(srcBitmap, Math.round(retX), Math.round(retY), Math.round(srcW), Math.round(srcH), null, false);
}


/**
 * 判断图片类型
 */
public static int getPicTypeByUrl(String url) {
    int picType = -1;
    if (url == null) {
        return picType;
    }
    if (url.equals("")) {
        return picType;
    }
    String[] picArray = url.split("/");
    String picStr = "";
    if (picArray.length > 0) {
        picStr = picArray[picArray.length - 1];
    } else {
        picStr = picArray[0];
    }
    if (picStr.toLowerCase().contains(".png")) {
        picType = 0;
    } else if (picStr.toLowerCase().contains(".jpg") || picStr.toLowerCase().contains(".jpeg")) {
        picType = 1;
    }
    return picType;
}


/**
 * 按质量压缩图片
 */
private byte[] compressBitmap(Bitmap bitmap, long sizeLimit) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int quality = 100;
    bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);

    // 循环判断压缩后图片是否超过限制大小
    while (baos.toByteArray().length / 1024 > sizeLimit) {
        // 清空baos
        baos.reset();
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
        quality -= 10;
    }

    return baos.toByteArray();
}


/**
 * 分享到小程序
 */
public void shareWxMini(String path, String title, Bitmap bitmap, int picType) {
    WXMiniProgramObject miniProgramObj = new WXMiniProgramObject();
    miniProgramObj.webpageUrl = "http://www.qq.com"; // 兼容低版本的网页链接
    miniProgramObj.miniprogramType = AppManager.isDebug() ? WXMiniProgramObject.MINIPROGRAM_TYPE_PREVIEW : WXMiniProgramObject.MINIPTOGRAM_TYPE_RELEASE;// 正式版:0,测试版:1,体验版:2
    miniProgramObj.userName = Constants.MINI_ID;     // 小程序原始id
    miniProgramObj.path = path;            //小程序页面路径;对于小游戏,可以只传入 query 部分,来实现传参效果,如:传入 "?foo=bar"
    WXMediaMessage msg = new WXMediaMessage(miniProgramObj);
    msg.title = title;                    // 小程序消息title
    msg.description = "";               // 小程序消息desc

    if (bitmap != null) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(picType == 0 ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG, 50, baos);
        msg.thumbData = compressBitmap(bitmap, 128);
    } 

    SendMessageToWX.Req req = new SendMessageToWX.Req();
    req.transaction = buildTransaction("miniProgram");
    req.message = msg;
    req.scene = SendMessageToWX.Req.WXSceneSession;  // 目前只支持会话
    api.sendReq(req);
}

方法二:重新用 Canvas 绘制一张图,将所要展示的图片居中展示

/**
 * 居中裁剪图片
 */
public static Bitmap drawWXMiniBitmap(Bitmap bitmap, int width, int height) {
    Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    // 用这个Bitmap生成一个Canvas,然后canvas就会把内容绘制到上面这个bitmap中
    Canvas mCanvas = new Canvas(mBitmap);
    // 绘制画笔
    Paint mPicturePaint = new Paint();
    // 绘制背景图片
    mCanvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPicturePaint);
    // 绘制图片的宽、高
    int width_head = bitmap.getWidth();
    int height_head = bitmap.getHeight();
    // 绘制图片--保证其在水平方向居中
    mCanvas.drawBitmap(bitmap, (width - width_head) / 2, (height - height_head) / 2,
        mPicturePaint);
    // 保存绘图为本地图片
    mCanvas.save();
    mCanvas.restore();
    return mBitmap;
}

/**
 * 按指定宽高缩放图片
 */
public static Bitmap resizeBitmap(Bitmap bitmap, int w, int h) {
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();

    float scaleWidth = ((float) w) / width;
    float scaleHeight = ((float) h) / height;

    Matrix matrix = new Matrix();
    matrix.postScale(scaleWidth, scaleHeight);

    Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width,
            height, matrix, true);
    return resizedBitmap;
}

// 调用
Bitmap bitmap = BitmapUtil.drawWXMiniBitmap(bitmap, bitmap.getHeight() * 5 / 4, bitmap.getHeight());
if (BitmapUtil.isOverSize(bitmap, 128)) {// 判断是否超过128kb,方法略
    bitmap = Utils.resizeBitmap(bitmap, 300, 240);
}
// 裁剪缩放完成后如果还大于128kb,再进行质量压缩,压缩方法用方法一
// ...

方法三:
这里没写具体的代码,只记录一下思路。
把图片放到宽高固定5:4的ImageView上(如果图片被拉伸就先裁剪再放上去),然后对ImageView截图,得到的就已经是压缩好的图片了。

关于压缩图片的坑
我最开始用的Luban压缩,毕竟是GitHub大神仿微信压缩的库,肯定没有问题,就是用起来麻烦一些,需要保存图片文件并转成Bitmap。得到的图片虽然已经被压缩到小于128kb,但还是分享不了。我以为是方法的问题,看日志发现是压缩好的Bitmap转成byte数组的锅,转换后大小变大了,超过128kb所以分享不了。
最后我用方法一,直接判断byte数组的大小进行压缩。成功分享。
如果有不对的地方欢迎大佬们留言指正。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值