将 apiCloud 开发app的图片上传流程,完整封装成了一个页面,页面处理一些必备的处理库外和css外 ,还需要依赖jquery 库,不过可以不管,页面默认使用cnd引用。

页面使用接口如下:pageParam:{toPX:200,toPY:150,toNm:'imgName'},这是传入页面的参数,用于定义裁剪框的大小(单位px),裁剪框自动屏幕居中。toNm指定保存到服务器上图片的名字,格式为jpg,不用指定。

返回结果通过事件的形式传递。页面处理成功后会触发一个名为 "imcp_out" 的事件,服务器图片信息 在 out 参数中。页面代码如下:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<title>本地选择、缩放、裁剪、上传 图片 (效果优化,增加多点触控缩放 和 上传进度条显示 ,并且把截图的宽高封装成接口,通过页面参数传入)</title>
<link rel="stylesheet" href="ion.rangeSlider.css">
<link rel="stylesheet" href="ion.rangeSlider.skinHTML5.css">
<style type="text/css">
/*div{box-sizing:border-box;}*/
*{margin:0;padding:0;}
.imcp_container{
width:100%;
margin:0 auto;
overflow: hidden;
position: relative;
}
.imcp_container img{
display: block;
position: absolute;
width:100%;
}
.imcp_container .kuang{
position: absolute;
left:10%;
top:10%;
width:80%;
height:80%;
/*border:1px solid #841;*/
}
.imcp_container .Layer{
position: absolute;
background-color: rgba(0,0,0,0.4);
}
.imcp_container .top{
top:0;
left:0;
width:100%;
height:10%;
}
.imcp_container .bottom{
bottom:0;
left:0;
width:100%;
height:10%;
}
.imcp_container .left{
top:10%;
left:0;
width:10%;
height:80%;
}
.imcp_container .right{
top:10%;
left:90%;
width:10%;
height:80%;
}
.imcp_content .ctrlBar{
opacity: 0.6;
display: block;
position: absolute;
bottom: 5px;
left:10%;
width: 80%;
}
.imcp_content .okClip{
position: absolute;
width:28px;
height:28px;
text-align: center;
line-height: 25px;
border-radius:50%;
padding:4px;
background-color:#ddd;
top:18px;
right:8px;
opacity: .5;
}
#showPicBtn{
position: absolute;
width:50px;
height:50px;
text-align: center;
line-height: 25px;
border-radius:50%;
padding:4px;
background-color:#ddd;
top:30px;
right:60px;
}
#showPicBtn img{
width:100%;
height:100%;
}
.imcp_content{
position: relative;
}
#example_id{
display: none;
}
.maskLyer{
position: fixed;
z-index: 1000;
top:0;
left:0;
background-color:rgba(0,0,0,0.6);
}
.maskLyer .uploadCont{
position: absolute;
top:250px;
height:60px;
width:100%;
text-align:center;
}
.maskLyer .uploadBtn{
margin:0 auto;
border-radius:30px;
width:180px;
height:60px;
line-height:60px;
text-align:center;
border:#F2F2F2 solid 1px;
color:#F2F2F2;
font-size:18px;
font-weight:bold;
}
.hover{
background-color:rgba(200,200,200,.5);
}
</style>
</head>
<body>
<div class="imcp_content">
<div class="imcp_container">
<img id="aimm" src="" />
<div class="kuang"></div>
<div class="top Layer"></div>
<div class="right Layer"></div>
<div class="bottom Layer"></div>
<div class="left Layer"></div>
</div>
<div class="ctrlBar">
<input type="text" id="example_id" name="example_name" value="100" />
</div>
<!-- <input class="ctrlBar" type="range" min="0" max="200" step="1" value="100"/> -->
<div class="okClip">OK</div>
<!--<div id="showPicBtn"><img src="" /></div>-->
</div>
<div class="maskLyer">
<div class="uploadCont">
<div class="uploadBtn" tapmode="hover">点击选择图片</div>
</div>
</div>
</body>
<script src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script>
<!--<script src="../../script/jquery-1.11.3.min.js"></script>-->
<script src="ion.rangeSlider.min.js"></script>
<script type="text/javascript" src="alloyimage.1.2b.js"></script>
<script type="text/javascript"> apiready=function(){
// checkLastLoad();
$(".maskLyer").css({"height":api.winHeight,"width":api.winWidth});
//计算屏幕的中心点
screenCenterX=Math.round(api.winWidth/2);
screenCenterY=Math.round(api.winHeight/2); aimImgw=api.pageParam.toPX;
aimImgh=api.pageParam.toPY; setLayPosi(); } function checkLastLoad(){
if (lastFg==0){
lastFg=1;
}
if (lastFg==1){
lastFg=2;
setLayPosi();
}
} var screenCenterX,screenCenterY;
var aimImgw,aimImgh;//目标图片的宽高,这是这个模块页面唯一的两个输入值,不能超出屏幕的宽高
var lastFg=0; $(function(){
/*
* 范围滑动插件
* https://github.com/IonDen/ion.rangeSlider
*
* 腾讯前端图片处理库
* http://alloyteam.github.io/AlloyPhoto/docs.html
*
* 待完善,加上上传进度条,增加多点触控缩放
*/
// checkLastLoad();
$("#example_id").ionRangeSlider({
min:50,
max:200,
step:1,
hideText: true,
postfix:"%",
onChange: function(obj){ // function-callback, is called on every change
var vl=obj.input.val();
var ltvl=parseInt((100-vl)/2)+'%';
var percent=vl+"%";
$aimImg.css({
width:percent,
left:ltvl,
top:ltvl
});
}
});
var winHeight=$(window).height();
$(".imcp_container").css({
height: winHeight+'px'
});
$("#example_id").show();
$aimImg=$(".imcp_container img");
$(".imcp_content .okClip").on('touchstart', function(event) {
api.showProgress({title: '努力上传中...',text: '先喝杯茶...'});
event.preventDefault();
/* Act on the event */
var $kuang=$(".imcp_container .kuang");
var kw=$kuang.width();
var kh=$kuang.height();
var kl=parseInt($kuang.css("left"));
var kt=parseInt($kuang.css("top"));
var iml=parseInt($aimImg.css("left"));
var imt=parseInt($aimImg.css("top"));
iml=iml?iml:0;
imt=imt?imt:0;
var clpl=kl-iml;
var clpt=kt-imt;
if (clpl<0 || clpt<0){
api.hideProgress();
api.alert({
title: '操作无效',
msg: '裁剪框无法完全覆盖图片',
buttons:['确定']
},function(ret,err){
});
return;
}
var oriImg=new Image();
oriImg.src=aimImg.src;
clipIMg(aimImg,oriImg,clpl,clpt,kw,kh);
}); $(".maskLyer .uploadBtn").on('touchend',function(){//用户点击图片上传按钮
pickImg(function(file){
//读取到file对象后,将其中数据读出来,放到img对象中
var reader=new FileReader();
reader.readAsDataURL(file);
reader.onload=function(){
$("#aimm").attr("src",this.result);
$(".maskLyer").hide();
}
});
});
}); //设置裁剪遮罩层的大小和位置
function setLayPosi(){
//设置界面上的显示框界面
if (aimImgw<=api.winWidth && aimImgh<=api.winHeight){
var lLeft=Math.round((api.winWidth-aimImgw)/2);
var lTop=Math.round((api.winHeight-aimImgh)/2);
$(".imcp_container .kuang").css({
"width":aimImgw+"px",
"height":aimImgh+"px",
"left":lLeft+"px",
"top":lTop+"px",
});
$(".imcp_container .top").css({
"width":api.winWidth+"px",
"height":lTop+"px",
"left":0+"px",
"top":0+"px",
});
$(".imcp_container .bottom").css({
"width":api.winWidth+"px",
"height":(lTop+aimImgh)+"px",
"left":0+"px",
"top":(lTop+aimImgh)+"px",
});
$(".imcp_container .left").css({
"width":lLeft+"px",
"height":aimImgh+"px",
"left":0+"px",
"top":lTop+"px",
});
$(".imcp_container .right").css({
"width":lLeft+"px",
"height":aimImgh+"px",
"left":(lLeft+aimImgw)+"px",
"top":lTop+"px",
});
}
} //从本地选择图片,通过回调函数传回图片对象(一个)
function pickImg(callBack){
var fileup=$('<input type="file" accept="image/*" />');
fileup.on('change',function(event) {
callBack(this.files[0]);
});
fileup.click();
} var temPicName; //对一个图片进行截取,输入图片dom元素,和截图位置及大小,输出一个图片对象
function clipIMg(nImg,oImg,x,y,w,h){
var nmg = $AI(nImg);
var omg = $AI(oImg);
var ratex=omg.width/nmg.width;
var ratey=omg.height/nmg.height;
var sw=parseInt(w*ratex);
var sh=parseInt(h*ratey);
var sl=parseInt(x*ratex);
var st=parseInt(y*ratey);
var ai=omg.clip(sl,st,sw,sh);//等比例在原图上裁剪
ai=ai.scaleTo(aimImgw,aimImgh);//缩放到指定的宽、高
var base64Img=ai.save("jpg",1);
temPicName="tem1.jpg";
base64ToImg(base64Img,function(){
upFile(temPicName);
});
} function upFile(url){
var model = api.require('model');
openProcess();//打开弧形进度条组件
// model.config({
// appId:'A6982657012078',
// appKey: '695B6394-5ABC-AE07-1214-182A459D562B',
// host: 'https://d.apicloud.com'
// });
model.uploadFile({
data:{
file:{
name:'1uyuser.jpg',
url:'fs://'+url
}
},
report:true
},function(ret, err) {
api.hideProgress();
if (ret) {
if (ret.state==0){//上传中
arcProObj.setValue({
id:arcProId,
value:ret.progress
});
}else{
if (ret.state==1){
// 成功后返回的数据: ret.body
arcProObj.close({id:arcProId});
api.sendEvent({
name: 'imcp_out',
extra: {out:ret.body}
});
//localStorage.imcp_out=ret.body;
api.alert({
title: '提示',
msg: '上传成功',
buttons:['确定']
},function(ret,err){
setTimeout(function(){
api.closeWin({});
},800);
});
}else{
alert("上传失败!"+JSON.stringify(ret));
}
}
} else {
alert("上传失败!"+JSON.stringify(ret));
}
});
} var arcProObj,arcProId;
function openProcess(){
arcProObj = api.require('arcProgress');
arcProObj.open({
type: 'sector',
centerX: screenCenterX,
centerY: screenCenterY,
radius: 60,
bgColor: '#999',
pgColor: '#444'
},function(ret,err){
arcProId=ret.id;
})
} function base64ToImg(str,callBack){//传入base64格式的图片,转化为本地图片,返回本地路径
var trans = api.require('trans');
str = str.replace('data:image/jpeg;base64,', '');
trans.saveImage({
base64Str:str,
imgPath:"fs://",
imgName:temPicName
},function(ret,err){
if(ret.status) {//若成功,则调用回调函数
//showFileAttr(temPicName);
callBack();
}else{
api.alert({msg:err.msg});
api.hideProgress();
}
});
} function showFileAttr(dir){
var fs = api.require('fs');
fs.getAttribute({
path: 'fs://'+dir
},function(ret,err){
if (ret.status) {
api.alert({msg:'文件属性:'+JSON.stringify(ret.attribute)});
}else{
api.alert({msg:err.msg});
}
});
} var $aimImg;
var aimImg=document.querySelector("#aimm");
var obj=document.querySelector(".imcp_container");
var ix,iy;
obj.addEventListener('touchstart',function(event){
if (event.targetTouches.length == 1) {
event.preventDefault();
var touch = event.targetTouches[0];
//getComputedStyle函数可参考网址:http://blog.sina.com.cn/s/blog_89cd68470101i108.html
var ox=parseInt(getComputedStyle(this,false)["left"]);
ox=ox?ox:0;
var oy=parseInt(getComputedStyle(this,false)["top"]);
oy=oy?oy:0;
var cLeft=parseInt(getComputedStyle(aimImg,false)["left"]);
cLeft=cLeft?cLeft:0;
var cTop=parseInt(getComputedStyle(aimImg,false)["top"]);
cTop=cTop?cTop:0;
var sx=ox+cLeft;
var sy=oy+cTop;
ix=touch.pageX-parseInt(sx);
iy=touch.pageY-parseInt(sy);
}
},false);
obj.addEventListener('touchmove',function(event){
// 如果这个元素的位置内只有一个手指的话
if (event.targetTouches.length == 1) {
    event.preventDefault();// 阻止浏览器默认事件,重要
var touch = event.targetTouches[0];
// 把元素放在手指所在的位置
var ax=parseInt(touch.pageX-ix);
var ay=parseInt(touch.pageY-iy);
var fLeft=parseInt(getComputedStyle(this,false)["left"]);
var fTop=parseInt(getComputedStyle(this,false)["top"]);
fLeft=fLeft?fLeft:0;
fTop=fTop?fTop:0;
var rx=ax-fLeft;
var ry=ay-fTop;
aimImg.style.left = rx+"px";
aimImg.style.top = ry+"px";
}
},false);
</script>
</html>

apiCloud图片选择、处理、上传模块的更多相关文章

  1. UEditor独立图片、文件上传模块

    百度的UEditor编辑器的强大之处不用多说,但是有时候我们只想用他的文件.图片上传模块,不想把这个编辑器加载出来,话不多说,直接上实现代码: 引用文件: <script src="~ ...

  2. 基于h5的图片无刷新上传(uploadifive)

    基于h5的图片无刷新上传(uploadifive) uploadifive简介 了解uploadify之前,首先了解来一下什么是uploadify,uploadfy官网,uploadify和uploa ...

  3. 基于SpringBoot从零构建博客网站 - 设计可扩展上传模块和开发修改头像密码功能

    上传模块在web开发中是很常见的功能也是很重要的功能,在web应用中需要上传的可以是图片.pdf.压缩包等其它类型的文件,同时对于图片可能需要回显,对于其它文件要能够支持下载等.在守望博客系统中对于上 ...

  4. 从web编辑器 UEditor 中单独提取图片上传,包含多图片单图片上传以及在线涂鸦功能

    UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码.(抄的...) UEditor是非常好用的富文 ...

  5. 百度在线编辑器UEditor(v1.3.6) .net环境下详细配置教程之更改图片和附件上传路径

    本文是接上一篇博客,如果有疑问请先阅读上一篇:百度在线编辑器UEditor(v1.3.6) .net环境下详细配置教程 默认UEditor上传图片的路径是,编辑器包目录里面的net目录下 下面就演示如 ...

  6. HTML5实现图片文件异步上传

    原文:HTML5实现图片文件异步上传 利用HTML5的新特点做文件异步上传非常简单方便,本文主要展示JS部分,html结构.下面的代码并未使用第三发库,如果有参照,请注意一些未展现出来的代码片段.我这 ...

  7. UEditor+七牛,实现图片直连上传

    最近做的项目,涉及到使用富文本编辑器,我选择了百度的UEditor.同时,我们的图片放在七牛云存储上.关于这两者间的集成,我写下一些个人的经验,与大家分享. 图片上传方案 目前来说,Web端基于七牛等 ...

  8. 【Web】前端裁剪图片,并上传到服务器(Jcrop+canvas)

    web网站中常常有的功能:上传头像.上传封面等:一般图片都有一定的比例限制,所以需要前端在上传图片时,进行裁剪,并把裁剪后的图片进行上传. 本例采用Jcrop插件实现裁剪效果,canvas裁剪图片,并 ...

  9. vue+element-ui中的图片获取与上传

    vue+element-ui中的图片获取与上传 工作上接触了一下图片的处理,图片的格式是文件流, 记录如下. 请求图片 请求图片的时候,带上{ responseType: 'blob' }, 否则图片 ...

  10. vue+Ueditor集成 [前后端分离项目][图片、文件上传][富文本编辑]

    后端DEMO:https://github.com/coderliguoqing/UeditorSpringboot 前端DEMO:https://github.com/coderliguoqing/ ...

随机推荐

  1. MySQL(Percona Server) 5.6 主从复制

    MySQL(Percona Server) 5.6.15 主库:192.168.2.21 从库:192.168.2.22 例如我们同步的数据库为:test. 如果需要同步多个数据库下面会有说明. My ...

  2. Android课程---关于下拉列表与状态栏提示的学习

    activity_ui7.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout x ...

  3. Thinking in Java——笔记(12)

    Error Handling with Exceptions The ideal time to catch an error is at compile time, before you even ...

  4. Sharepoint client model 中出现Cannot invoke HTTP DAV request. There is a pending query 的解决办法

    由于近期在某项目中使用sharepoint client 对象模型做项目 在sharepoint 2010环境下正常,但迁移到sharepoint 2013后报错,提示如下 Cannot invoke ...

  5. How to create a "BOOT USB DISK" for EXSI6.0

    1 准备工作 opensuse 13.2ESXi ISO文件  //vmware 官网下载 VMware-VMvisor-Installer-5.1.0-799733.x86_64.iso,XXXXX ...

  6. sql注入漏洞

    在这么多bug里给我印象最深的就是sql注入漏洞,看上去没有问题的代码却会因为用户的不正常输入而带来极其严重的问题. 现在给大家分享一下如何修复SQL注入漏洞.下面是网上的两种解决方法,其中第二方法有 ...

  7. WordPress基础:订阅源rss的使用

    设置->阅读,可设置rss显示效果 RSS源为:http://wordpress目录/feed 把这个地址放入你的rss阅读器进行订阅即可,最简单的就是使用QQ邮箱里面的阅读空间进行订阅.

  8. Mac上安装django

    参考:https://docs.djangoproject.com/en/1.9/topics/install/#installing-official-release 升级pip sudo pip ...

  9. visual studio2015使用git管理源代码

    1.注册https://git.oschina.net/ 2.注册好后,创建一个测试项目,如下图: 点击创建,如下: 上面的红框中的地址下面会用到. 3.git初始化设置 在本地电脑要安装git,打开 ...

  10. docker好文收藏

    深入浅出Docker(一):Docker核心技术预览 2. 核心技术预览 Docker核心是一个操作系统级虚拟化方法, 理解起来可能并不像VM那样直观.我们从虚拟化方法的四个方面:隔离性.可配额/可度 ...