首页 > 编程语言 >uniapp微信小程序图片裁剪插件,支持自定义尺寸、定点等比例缩放、拖动、图片翻转、剪切圆形/圆角图片、定制样式

uniapp微信小程序图片裁剪插件,支持自定义尺寸、定点等比例缩放、拖动、图片翻转、剪切圆形/圆角图片、定制样式

时间:2023-11-16 17:01:50浏览次数:38  
标签:插件 自定义 缩放 res 裁剪 common data 图片

uniapp微信小程序图片裁剪插件,支持自定义尺寸、定点等比例缩放、拖动、图片翻转、剪切圆形/圆角图片、定制样式,功能多性能高体验好注释全。

1.效果预览:

         

5.引入插件

项目代码:Homilier / qf-image-cropper · GitCode

使用HBuilder X导入项目 :图片裁剪插件 - DCloud 插件市场

平台兼容性

Vue2Vue3
App快应用微信小程序支付宝小程序百度小程序字节小程序QQ小程序
HBuilderX 3.1.0 app-vue × × × × ×
钉钉小程序快手小程序飞书小程序京东小程序
× × × ×
H5-SafariAndroid Browser微信浏览器(Android)QQ浏览器(Android)ChromeIEEdgeFirefoxPC-Safari
× × × × × ×

平台支持:

  1. 支持微信小程序:移动端、PC端、开发者工具
  2. 支持H5平台(2.1.0版本起)
  3. 支持APP平台(2.1.5版本起):Android、IOS
  4. 其他平台暂未测试兼容性未知

支持功能:

  1. 自定义裁剪尺寸
  2. 定点等比例缩放:移动端以双指触摸中心点为缩放中心点,PC端以鼠标所在点为缩放中心点
  3. 自由拖动:支持限制滑出边界,也支持回弹效果(滑动时可滑出边界,释放时回弹到边界)
  4. 图片翻转:在裁剪尺寸非 1:1 的情况下,翻转时宽高无法铺满裁剪区域时,图片会自动放大到合适尺寸
  5. 裁剪生成新图片
  6. 本地选择图片
  7. 可定制样式:可自由选择是否渲染裁剪边框、可伸缩裁剪顶角、参考线
  8. 裁剪圆角图片:圆形、圆角矩形 

属性说明

属性名类型默认值说明
src String   图片资源地址
width Number 300 裁剪宽度
height Number 300 裁剪高度
showBorder Boolean true 是否绘制裁剪区域边框
showGrid Boolean true 是否绘制裁剪区域网格参考线
showAngle Boolean true 是否展示四个支持伸缩的角
areaScale Number 0.3 裁剪区域最小缩放倍数
maxScale Number 5 图片最大缩放倍数
bounce Boolean true 是否有回弹效果:拖动时可以拖出边界,释放时会弹回边界
rotatable Boolean true 是否支持翻转
choosable Boolean true 是否支持从本地选择素材
angleSize Number 20 四个角尺寸,单位px
angleBorderWidth Number 2 四个角边框宽度,单位px
radius Number   裁剪图片圆角半径,单位px
fileType String png 生成文件的类型,只支持 'jpg' 或 'png'。默认为 'png'
delay Number 1000 图片从绘制到生成所需时间,单位ms
微信小程序平台使用 Canvas 2D 绘制时有效
如绘制大图或出现裁剪图片空白等情况应适当调大该值,因 Canvas 2d 采用同步绘制,需自己把控绘制完成时间
navigation Boolean true 页面是否是原生标题栏:
H5平台当 showAngle 为 true 时,使用插件的页面在 page.json 中配置了 "navigationStyle": "custom" 时,必须将此值设为 false ,否则四个可拉伸角的触发位置会有偏差。
注:因H5平台的窗口高度是包含标题栏的,而屏幕触摸点的坐标是不包含的
@crop EventHandle   剪裁完成后触发,event = { tempFilePath }。在H5平台下,tempFilePath 为 base64

基本用法

<template>
    <view>
        <block v-if="!imgPath">
            <image-cropper ref="cropper" :cropScale="cropScale" :src="imgSrc" @crop="handleCrop">
            </image-cropper>
        </block>
        <block v-if="imgPath">
            <view class="crop-cont cont_center">
                <image :src="imgPath" mode="widthFix"></image>
            </view>
            <view class="crop-bottom">
                <view class="crop-a left" @click="getBack">取消</view>
                <view class="crop-btn right" @click="onSubCrop">确定</view>
            </view>
        </block>

    </view>
</template>

<script>
    import common from '@/utils/common';
    import imageCropper from '@/components/custom/image-cropper/index';
    import {
        uploadHsFile,
        getUploadFile
    } from "@/api/main";

    export default {
        components: {
            imageCropper
        },
        data() {
            return {
                cropScale: '1:1', //裁剪比例,默认1:1
                width: 500,
                // imgSrc: 'https://img1.baidu.com/it/u=3893389324,4043822814&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800',
                imgSrc: null, //需要裁剪地址
                imgPath: null, //裁剪后图片地址
                isfrom: null, //页面来源
            };
        },
        onl oad(options) {
            if (options) {
                if (options.isfrom) {
                    this.isfrom = options.isfrom;
                }
                if (options.scale) { //裁剪比例
                    this.cropScale = options.scale;
                }
                if (options.src) { //需要裁剪的地址
                    this.imgSrc = options.src;
                }
            }
            if (!common.isEmpty(this.storage.get('fileData'))) {
                this.storage.remove('fileData');
            }
        },
        methods: {
            handleCrop(e) {
                let that = this;
                if (e && e.tempFilePath) {
                    var filePath = null;
                    // #ifdef H5
                    // 返回besa64 {tempFilePath: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwA…qD4BlmXardc/z2wLW/we1LoP21+aEvgAAAABJRU5ErkJggg=='}
                    filePath = e.tempFilePath;
                    // #endif
                    // #ifdef MP-WEIXIN
                    // 返回缓存地址 {tempFilePath: "http://tmp/92DOAKXWBPmrb8fd3ad722b9693120bf7ab6dbda5f18.png"}
                    var filePaths = e.tempFilePath;
                    uni.getFileSystemManager().readFile({
                        filePath: filePaths, //选择图片返回的相对路径
                        encoding: 'base64', //编码格式
                        success: res => { //成功的回调
                            //console.log('data:image/png;base64,'+res.data)
                            filePath = 'data:image/png;base64,' + res.data;
                        }
                    })
                    // #endif
                    this.imgPath = filePath;
                }
            },
            onSubCrop() { //确定
                this.uploadHsFile(this.imgPath);
            },
            async uploadHsFile(imageData) { //上传base64格式图片
                let that = this;
                let temp = {
                    imageData: imageData
                }
                await uploadHsFile(temp).then((res) => {
                    if (res.retCode == 200) {
                        var list = [];
                        if (res.data) {
                            var obj = {
                                url: common.getViewImageUrl(res.data),
                                fileReturnId: res.data,
                                type: "image"
                            }
                            list.push(obj);
                        }
                        var params = {
                            isfrom: that.isfrom,
                            imgList: list
                        };
                        console.log(params)
                        that.storage.set('fileData', params);
                        that.getBack();
                    } else {
                        common.toast(res);
                    }
                }).catch((err) => {
                    common.toast('图片发送失败');
                })
            },
            async getUploadFile(file) { //上传file格式图片
                let that = this;
                let temp = {
                    url: file.path
                }
                await getUploadFile(temp).then((res) => {
                    if (res.retCode == 200) {
                        if (res.retData) {
                            console.log(res.retData)
                            var list = [];
                            if (res.retData.length > 0) {
                                res.retData.forEach((v, index) => {
                                    var obj = {
                                        url: common.getViewImageUrl(v.fileReturnId),
                                        fileReturnId: v.fileReturnId,
                                        type: "image"
                                    }
                                    list.push(obj);
                                })
                            }
                            var params = {
                                isfrom: that.isfrom,
                                imgList: list
                            };
                            console.log(params)
                            that.storage.set('fileData', params);
                            that.getBack();
                        }
                    } else {
                        common.toast(res);
                    }
                }).catch((err) => {
                    common.toast('图片发送失败');
                })
            },

            getBack() { //取消返回
                common.getUniBack(1)
            },

        }
    };
</script>

<style>
    .crop-cont {
        width: 100%;
        height: 100vh;
        padding: 30rpx 50rpx;
        background: #333;
    }

    .crop-cont>image {
        display: block;
        width: 100%;
    }


    .crop-bottom {
        width: 100%;
        overflow: hidden;
        background: #fff;
        padding: 20rpx;
        position: fixed;
        left: 0;
        bottom: 0;
        z-index: 10;
    }

    .crop-a {
        width: 120rpx;
        line-height: 60rpx;
        font-size: 30rpx;
        color: #027BFF;
        text-align: center;
    }

    .crop-btn {
        width: 120rpx;
        line-height: 60rpx;
        font-size: 30rpx;
        color: #fff;
        background: #027BFF;
        text-align: center;
        border-radius: 16rpx;
    }
</style>

使用说明

1.建议在pages.json中将引用插件的页面添加一下配置禁止下拉刷新和禁止页面滑动,防止出现性能或页面抖动等问题。

{
    "enablePullDownRefresh": false,
    "disableScroll": true
}

2.建议使用本插件不要设置过大宽高的目标图片尺寸,建议1365x1365以内,否则可能会导致如下问题:

1.界面卡顿,内存占用过高
2.生成图片失真(模糊)
3.确定裁剪后一直显示 `裁剪中...`,该问题是由 `uni.canvasToTempFilePath` 无法回调导致,不同平台不同设备限制可能有所不同。

3.如裁剪后的图片存在偏移的问题,请检查是否受自己项目中父组件或全局样式影响。 4.src属性设置网络图片时,图片资源必须是能触发 getImageInfo API 的 success 回调才可用于插件裁剪。因此小程序平台获取网络图片信息需先配置download域名白名单才能生效。

 

标签:插件,自定义,缩放,res,裁剪,common,data,图片
From: https://www.cnblogs.com/czhowe/p/17836721.html

相关文章

  • 如何通过 wireshark 捕获 C# 上传的图片
    一:背景1.讲故事这些天计划好好研究下tcp/ip,以及socket套接字,毕竟工控中设计到各种交互协议,如果只是模模糊糊的了解,对分析此类dump还是非常不利的,而研究协议最好的入手点就是用抓包工具wireshark,废话不多说,这篇通过wireshark提取一个小图片作为入手。二:wireshark图片抓包1......
  • 视频直播系统源码,自定义背景和状态管理
    视频直播系统源码,自定义背景和状态管理1.源码 Future<T>showModalBottomSheet<T>({  @requiredBuildContextcontext,  @requiredWidgetBuilderbuilder,  ColorbackgroundColor,  //面板背景颜色  doubleelevation,  ShapeBordershape,  Clipcl......
  • 打印表格图片发黑,如何处理
    先创建一个WORD空白页,插入要打印的图片将布局设为【浮于文字上方】图片设置......
  • Java中的Comparator自定义排序
    需求:将指定数据中的数据,按照字母中包含的数字大小进行排序测试代码:publicstaticvoidmain(String[]args){List<String>list=newArrayList<>();list.add("QW34");list.add("QW21");list.add("QW12");list.add("QS34"......
  • vue中el-upload结合vuedraggable实现图片的上传、排序、删除以及预览等功能_element u
    <template><div><ulclass="el-upload-listel-upload-list--picture-card"style="display:flex;"><div><!--start:拖拽开始end:拖拽结束imageLists:需要展示图片的数组-->......
  • 图片资源中转站
    ......
  • javascript promise all实现图片顺序加载
    不使用promise时是异步加载,图片加载的顺序不固定<!doctypehtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,user-scalable=no,initial-scale=1......
  • 贷款额度图片生成器,在线制作成功审核通过,易语言画板生成实现
    用易语的画板加了一个网上贷款额度申请图+通过图,原有信息都被PS擦掉了,被擦掉的部分我加入了自己黑月透明标签,然后加了很多的编辑框,而编辑框是通过用户输入信息的,它都对应着每一个标签信息,我们点击按钮后要实现的功能就是标签的内容=编辑框这种效果,然后审核通过部分要加一些标签和......
  • 成品直播源码,JAVA获取图片的宽、高和大小
    成品直播源码,JAVA获取图片的宽、高和大小如果是本地磁盘文件     Filefile=newFile("C:\\Users\\root\\Desktop\\test.jpg");    BufferedImagebufferedImage=ImageIO.read(newFileInputStream(file));    intheight=bufferedImage.getHei......
  • 短视频app源码,自定义快速滚动条FastScrollBar
    短视频app源码,自定义快速滚动条FastScrollBarAndroidMainfest.xml中  <activityandroid:name=".MainActivity"      android:theme="@style/FastScrollTheme">      <intent-filter>        <actionandroid:name="androi......