实现图片自动居中裁剪

问题描述:

由于后台返回图片的大小不一致,但是前端要求把他们展示成大小一致且不变形。

小程序使用mode:aspectFill

但是如果是pc端和移动端。应该如何实现img标签图片的居中和自动裁切?

 

问题解决:

1. 非真正的裁剪

---------》即只进行前端预览时裁剪

1.1  使用css background

(不推荐,因为不方便维护。当需要动态改变时需要去操作单独的style)

<div style="background-image:url(这里填写图片的路径});
    background-repeat: no-repeat;
    background-position:center center;
    background-size: cover;
    width:100px;
    height:100px;">
</div>	 ​

简单说明一下background-size 的属性,因为被W3C讲得有点绕,总结就是:

cover:让图片填充满父节点,超出部分隐藏,仅显示中间,这才是我们想要的效果。

contain:让图片根据父节点宽高等比例缩放。

 

1.2 使用css3 object-fit属性

(css3新增属性,可能会有浏览器兼容问题)

这个CSS属性可以达到最佳最完美的居中自动剪裁图片的功能。

.aspectFill img{
    width: 200px;
    height: 200px;
    object-fit: cover;
}
object 属性有5个属性值,具体含义如下;
  • fill: 中文释义“填充”。默认值。图片拉伸填满容器, 不保证保持原有的比例缩放。
  • contain: 中文释义“包含”。保持原有尺寸比例缩放。长边匹配,短边留空。
  • cover: 中文释义“覆盖”。保持原有尺寸比例缩放。短边匹配,裁剪过长区域。即是我们想要的效果
  • none: 中文释义“无”。保持原有尺寸比例。不缩放。
  • scale-down: 中文释义“降低”。如若依次设置了none或contain, 最终呈现的是尺寸比较小的那个。

 

 

 

1.3 套一个父级元素,居中定位,超出部分隐藏

---------》(不会有浏览器兼容问题)

使用一个与目标图片大小一致的div, 设置overflow: hidden;

里面的 img标签,图片用absolute定位设置为居中

将图片宽高按比例缩放。

html

<!-- 这个div设置为和img图片同样的宽高,并且用absolute定位设置为居中 -->
<div class="banner-img__wrapper">
    <img src="url" class="banner-img">
</div>

css

.banner-img__wrapper {
    position: relative;
    /* 目标宽高 */
    width: 100px; 
    height: 100px;
    overflow: hidden;
}
.banner-img{
    position: absolute;
    left: 50%;
    top: 50%;
    transform-origin: left top;
    /* 图片原宽高去缩放,选择宽高缩放比中较大的一个 */
    /* 如这里图片原宽高是 496*640, 宽缩放比=100/496,高缩放比=100/640,则较大的为100/496~0.2 */
    transform: scale(0.2) translate(-50%, -50%);
}

uploading.gif正在上传…重新上传取消

 

1.4  将1.3写成一个组件

待整理~

 

2. 真正的裁剪

2.1 利用canvas进行裁剪

利用wx.getImageInfo 获取图片信息res,如宽高等,然后锁定宽高比(按照 canvas_width / canvas_height)

进行图片缩放裁剪,满足短边全部显示,长边的裁剪两边,只显示中间

let img_width;
let img_height;
// 裁剪正方形/长方形
// 需设置图片有在合法域名中,才能拿到图片的信息!!
// res 为wx.getImageInfo 的返回值
img_width = res.width;
img_height = res.height;

let canvas_width = width; // 海报中给目标图片预留的宽、高
let canvas_height = height;
let clip_left,clip_top; //左偏移值,上偏移值
let clip_width,clip_height; //截取宽度,截取高度

// 按画布锁定宽高比, 满足短边,裁剪长边来剪裁图片,效果类似 aspectFill
clip_height = img_width * (canvas_height / canvas_width);
// 如果按照这个比例裁剪后的图片高度与原图高度还高,证明图片 高度是短边,宽度是长边
if(clip_height > img_height){ 
  clip_height = img_height;
  clip_width = img_height * (canvas_width / canvas_height);
  clip_left = (img_width - clip_width) / 2 + left;
  clip_top = 0 + top;
}else{
  clip_width = img_width;
  clip_left = 0 + left;
  clip_top = (img_height - clip_height) / 2 + top;
}

// url,图片水平偏移,图片垂直偏移,图片截取宽度,图片高度,图片理想水平偏移,图片理想高度偏移,
this.ctx.drawImage(url, clip_left, clip_top, clip_width, clip_height, left, top, canvas_width, canvas_height);
this.ctx.restore();

 

如果文章对你有帮助,麻烦点赞哦,一起走花路吧~

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Uniapp可以通过引入第三方插件来实现图片裁剪功能,例如使用vue-cropper插件。 1. 安装vue-cropper插件 在项目根目录下打开命令行,输入以下命令安装vue-cropper插件。 ``` npm install vue-cropper ``` 2. 在页面中引入vue-cropper组件 在需要使用图片裁剪功能的页面中,引入vue-cropper组件。 ```html <template> <div> <vue-cropper ref="cropper" :img="img" :outputSize="{width: 300, height: 300}" :outputType="'jpeg'" :autoCrop="'true'" :canMove="'true'" :canZoom="'true'" :center="'true'" ></vue-cropper> <button @click="cropImage">裁剪图片</button> </div> </template> <script> import VueCropper from 'vue-cropper' export default { components: { VueCropper }, data() { return { img: '' } }, methods: { cropImage() { this.$refs.cropper.getCroppedCanvas().toBlob((blob) => { // 处理裁剪后的图片blob数据 }) } } } </script> ``` 3. 配置vue-cropper组件参数 在引入vue-cropper组件时,可以设置各种参数来达到自己的需求。常见的参数如下: - img:待裁剪图片地址 - outputSize:输出裁剪图片的尺寸 - outputType:输出裁剪图片的类型 - autoCrop:是否自动裁剪 - canMove:是否可以移动裁剪框 - canZoom:是否可以缩放裁剪框 - center:是否居中显示裁剪框 4. 裁剪图片 在点击裁剪按钮时,调用vue-cropper组件的getCroppedCanvas方法,获取裁剪后的图片blob数据。可以将blob数据上传到服务器或保存到本地。 ```javascript this.$refs.cropper.getCroppedCanvas().toBlob((blob) => { // 处理裁剪后的图片blob数据 }) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值