小程序图片自适应组件 仿微信聊天图片

本文分享了如何在小程序聊天中实现图片按微信QQ显示风格自适应缩放或截取的详细过程,包括尺寸计算、视窗区域设定及组件封装。通过JS动态调整图片大小,达到用户习惯的显示效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(转载请注明出处,本文章内容仅用于学习)


这几天开发小程序有个新需求,需要在聊天群中实现发送图片。
之前做聊天时已经把框架搭好,心想应该只需要后端增加上传图片的一系操作。
当然最后做出来是没问题,但是不论用哪个小程序的图片自动缩放/截取,显示效果都差强人意,最后综合考虑(百度了一大圈都没有🙃),只能手写图片自适应算法

最终想要实现的效果

目前这种聊天群的图片显示,用户最习惯的还是微信跟QQ的显示模式,参考微信的图片最终样式大体上划分为缩放与截取。
一种是不管图片原来有多大,发送后都会缩放到正常比例显示给用户,另一种通常是图片的宽高比例相差极大,如果缩放到用户的能一眼看完的程度,通常很不美观,所以一般会截取多余长/宽的那一部分,只显示一部分,用户如果想看完整图片需点击查看。
最后要能对图片的样式进行控制跟原来的一样。


解决方案

简略:使用js获取图片宽高并使用算法得出合理的显示宽高,最后将宽高动态赋值给wxml的图片,截取则利用图片定义的视窗区域。
一张图片在聊天室发出后,怎么知道这张图片要不要缩放/裁剪?这里做法是相对于屏幕,定义一块图片最大能显示多少的视窗区域,如果图片宽高任意一边超出这个视窗区,就要进行缩放操作,至于怎么缩放以及缩放多少合适请看代码。


考虑使用场景在数据量很多的消息列表中,最终选择将整体代码样式封装进组件中使用,实测使用组件加载图片跟不使用加载基本无差别。

组件代码
这里是针对聊天场景调试优化的版本,下面有通用版,不会创建组件的搜别人贴子,这里不做演示直接贴代码

JS

Component({
   
  lifetimes:{
   
    detached: function() {
   
      //console.log("组件实例被从页面节点树移除");
    },
    attached: function(){
   
      //console.log("组件实例进入页面节点树");
      
      var that = this;
      wx.getImageInfo({
    
        src: that.properties.imgUrl,
        success: function (res) {
     
          var imgWidth=res.width;
          var imgHeight=res.height;

          var maxPictureViewWidth = 280;//图片视窗最大宽度
          var maxPictureViewHeight = 220;//图片视窗最大高度

          var ratio = imgWidth/imgHeight;

          if(ratio<0.25 || ratio>2.2){
   //图片宽高比相差过大,可能需要截取
            //判断图片是过高还是过宽
            if(imgWidth>imgHeight){
   //图片过宽
              if(imgHeight>maxPictureViewHeight){
   //同时判断图片高度有没有大于视窗最大高度
                //图片过宽且图片高度大于视窗最大高度,依据高度缩减图片比例到视窗可见范围,宽度不管直接靠视窗截取多的部分不显示
                var product = maxPictureViewHeight/imgHeight;
                imgHeight=imgHeight*product
                imgWidth=imgWidth*product
                that.setData({
   
                  viewHeight:maxPictureViewHeight<imgHeight/2?maxPictureViewHeight:imgHeight/2,
                  viewWidth:maxPictureViewWidth<imgWidth/2?maxPictureViewWidth:imgWidth/2,
                  imgHeight:imgHeight/2,
                  imgWidth:imgWidth/2
                })
              }else{
   //图片高度小于视窗最大高度
                that.setData({
   
                  viewHeight:imgHeight/2,
                  viewWidth:maxPictureViewWidth,
                  imgHeight:imgHeight/2,
                  imgWidth:imgWidth/2
                })
              }
            }else{
   //图片过高
              if(imgWidth>maxPictureViewWidth){
   
                //图片过高且图片宽度大于视窗最大宽度,按照宽度缩减图片比例到视窗可见范围,高度不管直接靠视窗截取不显示
                var product = maxPictureViewWidth/imgWidth;
                imgHeight=imgHeight*product
                imgWidth=imgWidth*product
                that.setData({
   
                  viewHeight:maxPictureViewHeight,
                  viewWidth:maxPictureViewWidth,
                  imgHeight:imgHeight,
                  imgWidth:imgWidth
                })
              }else{
   //图片宽度小于视窗最大宽度
                that.setData({
   
                  viewHeight:maxPictureViewHeight,
                  viewWidth:imgWidth/2,
                  imgHeight:imgHeight/2,
                  imgWidth:imgWidth/2
                })
              }
            }
          }else{
   //图片宽高比相差不大,
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值