mui开发app之cropper裁剪后上传头像的实现

在大多数app项目中,都需要对用户头像的上传,之前做web开发的时候,我主要是通过input type=file的标签实现的,上传后,使用php对图片进行裁剪,这种方式比较传统简单。

此次app开发中我需要做到用户选择本地相册或者进行拍照,对照片进行裁剪,最后更新本地头像和服务器端的图片

我将要结合mui,cropper,jquery开发

实现思路:

1.用户点击头像,打开actionsheet

2.选择图片或者拍照后返回的图片绝对地址传入单独的裁剪页面,跳转到裁剪页面

3.裁剪页面裁剪后选择确认则将裁减后图片(注意:canvas使用base64,新图片不存在url)保存到localstorage中(其实是把整个图片保存到本地数据库中)

4.触发一个更新上一页头像的事件,返回上一页

5.看到图片已经更改

6.保存,上传到服务器(json)

实现工具和插件,直接看代码:

js

<script type="text/javascript" src="../js/jquery-1.11.2.min.js"></script>
<script src="../js/mui.min.js"></script>
<script type="text/javascript" src="../js/exif.js"></script>
<script src="../js/cropper.min.js"></script>
<script src="../js/fastclick.js"></script>

css

<link href="../css/mui.min.css" rel="stylesheet" />
<link href="../css/iconfont.css" rel="stylesheet" />
<link href="../css/cropper.css" rel="stylesheet" />

这里我们主要使用了一个cropper.js的插件,自行百度下载,目前比较好用的插件只有这个,大神的话自己写一个吧

注意cropper必须使用jquery,而jquery比较臃肿,在其他mui中尽量不要引入,我也是迫不得已,使用jq并非我本意

fastclcik是加速点击触发,一般在手机端开发其实用不到,因为一般使用tap,这里我加了进去,似乎对裁剪图片时手势操作有帮助,(+_+)?,不加也没有影响,测试过

iconfont是按钮图标

exif是可以检测图片拍摄时采用横向还是纵向

接下来可以开发了:

一共两个页面,

headinfo.html——编辑页面

cropper.html——裁剪页面

headinfo.html

<!doctype html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>我的资料</title>
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <link href="../css/mui.min.css" rel="stylesheet" />
        <link href="../css/style.css" rel="stylesheet" />
        <style type="text/css">
            .head {
                height: 40px;
            }

            .head {
                height: 40px;
            }

            #head {
                line-height: 40px;
            }

            .head-img {
                width: 40px;
                height: 40px;
            }

            #head-img1 {
                position: absolute;
                bottom: 10px;
                right: 40px;
                width: 40px;
                height: 40px;
            }

            .mui-fullscreen {
                position: fixed;
                z-index: 20;
                background-color: #000;
            }
        </style>
    </head>

    <body>
        <header class="mui-bar mui-bar-nav">
            <button type="button" class="mui-left mui-action-back mui-btn  mui-btn-link mui-btn-nav mui-pull-left">
                    <span class="mui-icon mui-icon-left-nav"></span>完成
            </button>
            <h1 class="mui-title">头信息</h1>
        </header>
        <div class="mui-content">
            <ul class="mui-table-view">
                <li class="mui-table-view-cell">
                    <a id="head" class="mui-navigate-right">个人头像
                        <span class="mui-pull-right head">
                            <img class="head-img mui-action-preview" id="head-img1" src=""/>
                        </span>
                    </a>
                </li>
                <li class="mui-table-view-cell">
                    <a class="mui-navigate-right">
                        Item 2
                    </a>
                </li>
                <li class="mui-table-view-cell">
                    <a class="mui-navigate-right">
                        Item 3
                    </a>
                </li>
            </ul>
        </div>

        <script src="../js/mui.min.js"></script>
        <script src="../js/app.js"></script>
        <script type="text/javascript">
            (function($) {
                $.init();

                $.plusReady(function() {
                    //初始化头像,和预览图
                    setTimeout(function() {
                        defaultImg();
                        setTimeout(function() {
                            initImgPreview();
                        }, 200);
                    }, 0);

                    //弹出菜单
                    mui(".mui-table-view-cell").on("tap", "#head", function(e) {
                        if(mui.os.plus) {
                            var a = [{
                                title: "拍照"
                            }, {
                                title: "从手机相册选择"
                            }];
                            plus.nativeUI.actionSheet({
                                title: "修改头像",
                                cancel: "取消",
                                buttons: a
                            }, function(b) {
                                switch(b.index) {
                                    case 0:
                                        break;
                                    case 1:
                                        getImage();
                                        break;
                                    case 2:
                                        galleryImg();
                                        break;
                                    default:
                                        break
                                }
                            })
                        }

                    });
                });

                /*
                 * 图片都保存到沙盒:_doc下
                 */

                //拍照
                function getImage() {
                    var c = plus.camera.getCamera();
                    c.captureImage(function(e) {
                        //存储到本地
                        plus.io.resolveLocalFileSystemURL(e, function(entry) {
                            cutImage(entry.toLocalURL());//裁剪图片,传入绝对地址
                        }, function(e) {
                            console.log("读取拍照文件错误:" + e.message);
                        });
                    }, function(s) {
                        console.log("error" + s);
                    }, {
                        filename: "_doc/head.jpg"
                    })
                }

                //相册
                function galleryImg() {
                    plus.gallery.pick(function(a) {
                        plus.io.resolveLocalFileSystemURL(a, function(entry) {       //entry为图片原目录(相册)流
                            cutImage(entry.toLocalURL());
                        }, function(e) {
                            console.log("读取图片错误:" + e.message);
                        });
                    }, function(a) {}, {
                        filter: "image"
                    })
                };

                //设置默认头像
                function defaultImg() {
                    var my_icon = app.getHeadImg();
                    if(my_icon != "") {
                        document.getElementById("head-img1").src = my_icon;
                    } else {
                        document.getElementById("head-img1").src = ‘../images/my_icon.jpg‘;
                    }
                }

                //预览图像
                document.getElementById("head-img1").addEventListener(‘tap‘, function(e) {
                    e.stopPropagation(); //阻止冒泡
                });

                function initImgPreview() {
                    var imgs = document.querySelectorAll("img.mui-action-preview");
                    imgs = mui.slice.call(imgs);
                    if(imgs && imgs.length > 0) {
                        var slider = document.createElement("div");
                        slider.setAttribute("id", "__mui-imageview__");
                        slider.classList.add("mui-slider");
                        slider.classList.add("mui-fullscreen");
                        slider.style.display = "none";
                        slider.addEventListener("tap", function() {
                            slider.style.display = "none";
                        });
                        slider.addEventListener("touchmove", function(event) {
                            event.preventDefault();
                        })
                        var slider_group = document.createElement("div");
                        slider_group.setAttribute("id", "__mui-imageview__group");
                        slider_group.classList.add("mui-slider-group");
                        imgs.forEach(function(value, index, array) {
                            //给图片添加点击事件,触发预览显示;
                            value.addEventListener(‘tap‘, function() {
                                slider.style.display = "block";
                                _slider.refresh();
                                _slider.gotoItem(index, 0);
                            })
                            var item = document.createElement("div");
                            item.classList.add("mui-slider-item");
                            var a = document.createElement("a");
                            var img = document.createElement("img");
                            img.setAttribute("src", value.src);
                            a.appendChild(img)
                            item.appendChild(a);
                            slider_group.appendChild(item);
                        });
                        slider.appendChild(slider_group);
                        document.body.appendChild(slider);
                        var _slider = mui(slider).slider();
                    }
                }

                //裁剪图片
                function cutImage(path) {
                    $.openWindow({
                        url: ‘cropper.html‘,
                        id: ‘cropper‘,
                        extras: {
                            path: path,
                        },
                        show: {
                            aniShow: ‘zoom-fade-in‘,
                            duration: 800
                        },
                        waiting: {
                            autoShow: true
                        }
                    });
                }

                //更新用户头像,主要是裁剪页面裁剪完后触发的
                function update_head_img() {
                    var my_icon = app.getHeadImg(); //返回的是base64图片格式
                    if(my_icon != "") {
                        document.getElementById("head-img1").src = my_icon;
                        document.querySelector("#__mui-imageview__group .mui-slider-item img").src = my_icon;
                    }
                }
                window.addEventListener("updateHeadImg", update_head_img); //添加自定义事件,其他页面调用
            })(mui);
        </script>
    </body>

</html>

cropper.html

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8">
        <title>裁剪头像</title>
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <link href="../css/mui.min.css" rel="stylesheet" />
        <link href="../css/iconfont.css" rel="stylesheet" />
        <link href="../css/cropper.css" rel="stylesheet" />
        <style type="text/css">
            body {
                background-color: #000000;
            }

            #cropper-example-1 {
                background-color: #000000;
                height: 93%;
                width: 100%;
                position: absolute;
            }

            #quxiao,
            #xuanzhuan,
            #xuanqu {
                font-size: 20px;
            }

            .divbut {
                width: 100%;
                text-align: center;
                position: fixed;
                z-index: 2;
                bottom: 0px;
                background-color: #000000;
                height: 7.5%;
                line-height: 50px;
            }

            .divbut>div:first-child {
                float: left;
                width: 20%;
            }

            .divbut>div:last-child {
                float: right;
                width: 20%;
            }

            img#im {
                height: 100%;
                width: 100%;
            }
        </style>
    </head>

    <body>
        <div id="cropper-example-1" class="mui-hidden">
            <img id="im" alt="Picture" />
        </div>

        <div class="divbut">
            <div>
                <p id="quxiao" class="iconfont icon-quxiao"></p>
            </div>
            <div>
                <p id="xuanqu" class="iconfont icon-queding"></p>
            </div>
        </div>
        <img src="" alt="" class="mui-hidden" id="im_exif" />

        <script type="text/javascript" src="../js/jquery-1.11.2.min.js"></script>
        <script src="../js/mui.min.js"></script>
        <script type="text/javascript" src="../js/exif.js"></script>
        <script src="../js/cropper.min.js"></script>
        <script src="../js/fastclick.js"></script>
        <script src="../js/app.js"></script>

        <script>
            $(function() {
                //尽量用一下fastclick
                FastClick.attach(document.body);
                ! function() {
                    var i = {
                        aspectRatio: 1 / 1
                    };
                }()
            });

            (function(c) {
                var Cro = function() {}
                c.extend(Cro.prototype, {
                    orientation: null,
                    urldata: null,
                    view: null,
                    num: 0,
                    sbx: null,
                    sby: null,
                    n: 0,
                    onReady: function() {
                        var that = this;
                        mui.init();
                        that.bindEvent();
                        that.view = plus.webview.currentWebview();

                        var img = document.getElementById("im_exif");
                        img.src = that.view.path;
                        img.addEventListener("load", function() {
                            //exif调整图片的横竖
                            EXIF.getData(this, function() {
                                var orientation = EXIF.getAllTags(this).Orientation;
                                $("#im").attr("src", that.loadcopyImg(img, orientation));
                                document.getElementById("cropper-example-1").classList.remove("mui-hidden"); //显示裁剪区域
                                that.cropperImg();
                            });
                        })
                    },
                    cropperImg: function() {
                        var that = this;
                        $(‘#cropper-example-1 > img‘).cropper({
                            aspectRatio: 1 / 1,
                            autoCropArea: 1,
                            strict: true,
                            background: false,
                            guides: false,
                            highlight: false,
                            dragCrop: false,
                            movable: false,
                            resizable: false,
                            crop: function(data) {
                                that.urldata = that.base64(data);
                            }
                        });
                    },
                    loadcopyImg: function(img, opt) {
                        var that = this;
                        var canvas = document.createElement("canvas");
                        var square = 500;
                        var imageWidth, imageHeight;
                        if(img.width > img.height) {
                            imageHeight = square;
                            imageWidth = Math.round(square * img.width / img.height);
                        } else {
                            imageHeight = square; //this.width;
                            imageWidth = Math.round(square * img.width / img.height);
                        }
                        canvas.height = imageHeight;
                        canvas.width = imageWidth;
                        if(opt == 6) {
                            that.num = 90;
                        } else if(opt == 3) {
                            that.num = 180;
                        } else if(opt == 8) {
                            that.num = 270;
                        }
                        if(that.num == 360) {
                            that.num = 0;
                        }

                        var ctx = canvas.getContext("2d");
                        ctx.translate(imageWidth / 2, imageHeight / 2);
                        ctx.rotate(that.num * Math.PI / 180);
                        ctx.translate(-imageWidth / 2, -imageHeight / 2);
                        ctx.drawImage(img, 0, 0, imageWidth, imageHeight);
                        var dataURL = canvas.toDataURL("image/jpeg", 1);
                        return dataURL;
                    },
                    bindEvent: function() {
                        var that = this;
                        document.getElementById("quxiao").addEventListener("tap", function() {
                            mui.back();            //取消就直接返回
                        });
                        document.getElementById("xuanqu").addEventListener("tap", function() {
                            app.setHeadImg(that.urldata);
                            var preView = plus.webview.getWebviewById(‘user/headinfo‘);
                            mui.fire(preView, ‘updateHeadImg‘);            //触发上一个页面刷新图片事件
                            mui.back();
                        });
                    },
                    base64: function(data) {
                        var that = this;
                        var img = document.getElementById("im");

                        var canvas = document.createElement("canvas");
                        //像素
                        canvas.height = 500;
                        canvas.width = 500;
                        var bx = data.x;
                        var by = data.y;
                        var ctx = canvas.getContext("2d");
                        ctx.drawImage(img, bx, by, data.width, data.height, 0, 0, 500, 500);
                        var dataURL = canvas.toDataURL("image/jpeg", 1.0);            //第二个参数是质量
                        return dataURL;
                    }
                });

                var cro = new Cro();

                c.plusReady(function() {
                    cro.onReady();
                })
            })(mui)
        </script>
    </body>

</html>

效果图:

时间: 2024-10-11 03:32:09

mui开发app之cropper裁剪后上传头像的实现的相关文章

HTML5 开发APP(打开相册以及图片上传)

我们开发app,常常会遇到让用户上传文件的功能.比如让用户上传头像.我公司的业务要求是让用户上传支付宝收款二维码,来实现用户提现的功能.想要调用相册要靠HTML Plus来实现.先上效果图 基本功能是点击按钮就上传图片,然后获取到图片在服务器上的路径. 首先我们要打开相册,使用gallery模块管理系统相册来打开相册 mui('#shangchuan')[0].addEventListener('tap',function(){ chooseImg(); }) function chooseIm

file API+JCrop 选择、裁剪并上传头像

file API,直接读取本地文件,绕过了后台处理再返回前台的过程,使编程更简单.fileAPI和JCrop的结合使用上传头像. 1.html部分 <input id="demo" type="file" onchange="showPic();"/> <img id="avatar" src=""> 2.fileAPI预览图片(jquery) <script type=&qu

mui开发app之js将base64转图片文件

之前我已经做过一个利用cropper裁剪并且制作头像的功能.如何在mui app中实现相册或相机获取图片后裁剪做头像请看另一篇博客:mui开发app之cropper裁剪后上传头像的实现 但是当时裁剪后图片是保存为base64格式的,这是h5 canvas建议使用的图片传输方式. 很多时候很多api,比如mui中第三方插件map中有一个setIcon传入的必须是本地的图片文件地址,目前的第三方地图系统任然不支持base64的标注图,所以折腾了一晚之后终于在native.js中找到了将base64转

Discuz!NT Flash无法上传头像,点击上传后无任何反应

最近在对一个Discuz!NT论坛的老项目进行维护和二次开发,遇到了论坛无法上传头像的问题.在网上找了相当多的资料,发现解决的方法基本是无效的.虽然有的状况一样,但是没有解决方法,后来自己研究了下也总算是解决了这个问题. 首先说明下出现无法上传头像的具体症状,大概的症状有下面这几点: 使用Flash头像上传时,点击上传图片,然后显示“图片载入中,请稍后的提示信息”和上传进度的百分比,最后却是没有任何的反应. 网上有部分网友说到进度到10%就没有任何反应,其实只是部分情况,如果传大图片的话会显示其

利用 MUI开发app, 如何实现侧滑菜单及其主体部分上下滑动

 利用mui开发APP 之侧滑菜单主内容滚动问题 MUI作为开发者常用的框架之一,其号称最接近原生APP体验的高性能前端框架.因此利用mui开发移动APP,可以为开发者提供很大的便利和接近原生的体验.但是,在实现一些复杂功能的过程中,难免遇到一些小问题.博主将以自己在项目开发中的一些的经验,陆续对mui使用中容易遇到的小问题,予以解答和分享,希望能帮到更多的开发者朋友. 最近,博主在项目开发过程中遇到这样一个问题,即利用mui侧滑菜单模块,实现APP的侧滑菜单效果时,侧滑菜单加入以后,将影响自身

wex5 教程 之 图文讲解 头像裁剪与上传

视频教程地址: http://v.youku.com/v_show/id_XMTgyMDE5NjEyOA==.html 一 效果演示 1.点击头像,弹出图片裁剪框 2,选择图片,裁剪,上传 3.上传成功后,头像图标更改 二 案例解读 案例目录 wex5为我们提供了一个picut图片裁剪案例,如下: 组件部局 加入file标签用来打开文件管理器进行图片选择,div标签进行图片预览,image标签为裁剪图片 后端服务 后端接收请求参数后,对路径进行了拼接,创建文件流,并创建文件,成功后将成功信息传给

上传头像裁剪功能

我之前做项目的时候有需求是需要实现上传头像裁剪再上传到服务器,所以上网看了一下别人写的案例.方法.文章,浪费了1天的时间,最后才跌跌碰碰的终于写了出来. 现在给大家分享一下吧. 所用到的js文件 cropper.min.js, canvas-to-blob.js(这个是IE上需要用到的,不然会不支持转blob) jquery.min.js, bootstrap.min.js ajaxfileupload.js css文件 cropper.min.css,bootstrap.min.css htm

android app崩溃日志收集以及上传

源码获取请到github:https://github.com/DrJia/AndroidLogCollector 已经做成sdk的形式,源码已公开,源码看不懂的请自行google. 如果想定制适应自己app的sdk请自行fork. AndroidLogCollector android app崩溃日志收集sdk 1.0 作者:贾博士 崩溃日志收集方法: 1.LogCollector是lib包,在需要添加崩溃日志sdk的工程中导入此包. 2.导入lib后,在自己的工程的AndroidManife

vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理

一.前言 三年.net开发转前端已经四个月了,前端主要用webpack+vue,由于后端转过来的,前端不够系统,希望分享下开发心得与园友一起学习. 图片的上传之前都是用的插件(ajaxupload),或者传统上传图片的方式,各有利弊:插件的问题是依赖jq并且会使系统比较臃肿,还有传统的web开发模式 前后端偶尔在一起及对用户体验要求低,现在公司采用webpack+vue+restfullApi开发模式 前后端完全分离,遵从高内聚,低偶尔的原则,开发人员各司其职,一则提升开发效率(从长期来看,短期