apiCloud图片选择、处理、上传模块

时间:2021-11-03 21:54:32

将 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的图片无刷新上传&lpar;uploadifive&rpar;

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

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

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

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

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

  5. 百度在线编辑器UEditor&lpar;v1&period;3&period;6&rpar; &period;net环境下详细配置教程之更改图片和附件上传路径

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

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

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

  7. UEditor&plus;七牛,实现图片直连上传

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

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

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

  9. vue&plus;element-ui中的图片获取与上传

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

  10. vue&plus;Ueditor集成 &lbrack;前后端分离项目&rsqb;&lbrack;图片、文件上传&rsqb;&lbrack;富文本编辑&rsqb;

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

随机推荐

  1. 《一个操作系统的实现》 ubuntu系统环境配置

    <一个操作系统的实现> ubuntu系统环境配置 电脑之前已经安装了gcc. 一.nasm安装:sudo apt-get install nasm或官网下载http://sourcefor ...

  2. SQL DDL

    Sql语言被分为四大类:数据查询语言(DQL),数据操纵语言(DML),数据定义语言(DDL),数据控制语言(DCL). 1. 数据查询语言(DQL) 数据查询语言基本结构由select子句,from ...

  3. 【leetcode】 Unique Binary Search Trees II &lpar;middle&rpar;&star;

    Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For e ...

  4. 从客户端&lpar;Content&equals;&quot&semi;&lt&semi;p&gt&semi;SF&lt&semi;&sol;p&gt&semi;&quot&semi;&rpar;中检测到有潜在危险的 Request&period;Form 值

    出现这个问题,一般是由于.Net Framework 使用了4.0或以上版本造成的.(从 .Net Framework 4.0 开始,ASP.NET开始强制检测Request参数安全),而我们可以通过 ...

  5. build tree

    有二叉树的前序遍历和后序遍历,构造二叉树 /** * Definition for binary tree * public class TreeNode { * int val; * TreeNod ...

  6. C51的编程规范

    现在单片机的程序设计,C51已经得到广泛的推广和应用,算是单片机的主流设计程序,甚至可以说作为单片机开发人员必须要掌握的一门语言了.作为一门工具,最终的目的就是实现功能.在满足这个前提条件下,我们希望 ...

  7. c&num;读取xml文件配置文件Winform及WebForm-Demo具体解释

    我这里用Winform和WebForm两种为例说明怎样操作xml文档来作为配置文件进行读取操作. 1.新建一个类,命名为"SystemConfig.cs".代码例如以下: < ...

  8. SpringMvc通过&commat;Value&lpar; &rpar; 给静态变量注入值

    spring 不允许/不支持把值注入到静态变量中,如: @Value("${ES.CLUSTER_NAME}")private static String CLUSTER_NAME ...

  9. nGrinder性能测试平台的安装部署

    1.从GitHub下载war包: https://github.com/naver/ngrinder/releases 2.把ngrinder-controller-3.4.2.war重命名为ngri ...

  10. Singleton(单例)

    意图: 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 适用性: 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时. 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代 ...

相关文章