├── README.md ├── h5uploader_lib ├── bin │ └── h5uploader │ │ ├── h5uploader.d.ts │ │ ├── h5uploader.js │ │ └── h5uploader.min.js ├── package.json └── src │ ├── h5uploader.d.ts │ ├── h5uploader.js │ └── wxuploader.js └── test └── Main.ts /README.md: -------------------------------------------------------------------------------- 1 | # egret-album-tool 2 | 调用用户手机相册,实现照片的预览和上传。注意仅支持浏览器运行模式!APP打包模式是不支持的,需要另外的实现方式。 3 | 4 | 使用方式: 5 | 6 | ###第一步:配置第三方库### 7 | 8 | * 将本库中的ext目录,放置到您的项目目录下(放到别的路径下也可以,根据您的需求请自便) 9 | * 打开项目的egretProperties.json文件,在"modules"数组中增加:{"name": "uploader","path": "ext/uploader"} 10 | * 如果引用不到,请检查路径设置是否正确 11 | 12 | ###第二步:调用### 13 | 14 | ``` 15 | //调用相册,选择一张图片 16 | selectImage(this.selectedHandler,this); 17 | //在回调函数中,接收3个参数: 18 | //thisRef : 就是this的引用,上面传入的那个this 19 | //imgURL : 是选择的图片的缩略图的字符串数据(不是原图),您可以用RES加载,来实现预览 20 | //file : 就是选择的那个照片文件引用,如果要上传原始数据,需要引用 21 | private selectedHandler(thisRef:any,imgURL:string,file:Blob):void { 22 | //用RES加载,即可显示到Egret中实现预览 23 | RES.getResByUrl(imgURL,thisRef.compFunc,thisRef,RES.ResourceItem.TYPE_IMAGE); 24 | } 25 | ``` 26 | 27 | ``` 28 | //如果要上传,需要获取照片的原始数据,传递的参数是: 29 | //file : 就是上面selectedHandler回调中得到的那个照片文件引用 30 | //bytesHandler : 回调函数,因为加载是异步的,加载完成后就调用回调函数 31 | //this : 同上 32 | getImageData(file,this.bytesHandler,this); 33 | //回调函数中,接收2个参数: 34 | //thisRef : this引用 35 | //imgBytes : 照片的原始数据,类型是ArrayBuffer 36 | private bytesHandler(thisRef:any,imgBytes:ArrayBuffer):void { 37 | console.log("大图数据:"+imgBytes); 38 | } 39 | ``` 40 | 41 | 已知问题: 42 | 43 | * iOS下用摄像头拍照的照片,角度不对(http://blog.csdn.net/cdnight/article/details/35236793) 44 | -------------------------------------------------------------------------------- /h5uploader_lib/bin/h5uploader/h5uploader.d.ts: -------------------------------------------------------------------------------- 1 | 2 | declare function selectImage(selectedHandler:Function,thisRef:any): void; 3 | declare function selectImageWX(selectedHandler:Function,thisRef:any): void; 4 | declare function getImageData(file:Blob,bytesHandler:Function,thisRef:any): void; 5 | declare function isWeixin():boolean; -------------------------------------------------------------------------------- /h5uploader_lib/bin/h5uploader/h5uploader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shaoruiguo on 15/6/13. 3 | */ 4 | var mime = {'png': 'image/png', 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'bmp': 'image/bmp'}; 5 | var selectedHandler; 6 | var bytesHandler; 7 | var thisRef; 8 | var MAX_HEIGHT = 300; 9 | function selectImage(selectedFunc,thisValue) { 10 | selectedHandler = selectedFunc; 11 | thisRef = thisValue; 12 | var fileInput = document.getElementById("fileInput"); 13 | if(fileInput==null){ 14 | fileInput = document.createElement("input"); 15 | fileInput.id = "fileInput"; 16 | fileInput.type = "file"; 17 | fileInput.accept = "image/*"; 18 | fileInput.style.height = "0px"; 19 | fileInput.style.display = "block"; 20 | fileInput.style.overflow = "hidden"; 21 | document.body.insertBefore(fileInput,document.body.firstChild); 22 | fileInput.addEventListener('change', tmpSelectFile, false); 23 | } 24 | setTimeout(function(){fileInput.click()},100); 25 | } 26 | function tmpSelectFile(evt) { 27 | //console.log("image selected..."); 28 | var file = evt.target.files[0]; 29 | var type = file.type; 30 | if (!type) { 31 | type = mime[file.name.match(/\.([^\.]+)$/i)[1]]; 32 | } 33 | var ret = myCreateObjectURL(file); 34 | tmpCreateImage && tmpCreateImage(ret,file); 35 | var fileInput = document.getElementById("fileInput"); 36 | fileInput.value=""; 37 | } 38 | function tmpCreateImage(uri,file) { 39 | var image = new Image(); 40 | image.onload = function(){ 41 | var canvas = document.createElement("canvas"); 42 | if(!isWeixin() && image.height > MAX_HEIGHT) { 43 | //宽度等比例缩放 44 | image.width *= MAX_HEIGHT / image.height; 45 | image.height = MAX_HEIGHT; 46 | var ctx = canvas.getContext("2d"); 47 | ctx.clearRect(0, 0, canvas.width, canvas.height); 48 | canvas.width = image.width; 49 | canvas.height = image.height; 50 | ctx.drawImage(image, 0, 0, image.width, image.height); 51 | var smallURL = canvas.toDataURL("image/png"); 52 | } else { 53 | smallURL = uri; 54 | } 55 | image.width = image.height = 1; 56 | selectedHandler & selectedHandler(thisRef,smallURL,file); 57 | } 58 | image.src = uri; 59 | image.style.visibility = "hidden"; 60 | document.body.appendChild(image); 61 | } 62 | function myCreateObjectURL(blob){ 63 | if(window.URL != undefined) 64 | return window['URL']['createObjectURL'](blob); 65 | else 66 | return window['webkitURL']['createObjectURL'](blob); 67 | } 68 | function myResolveObjectURL(blob){ 69 | if(window.URL != undefined) 70 | window['URL']['revokeObjectURL'](blob); 71 | else 72 | window['webkitURL']['revokeObjectURL'](blob); 73 | } 74 | 75 | function getImageData(file,bytesFunc,thisValue) { 76 | bytesHandler = bytesFunc; 77 | thisRef = thisValue; 78 | try{var reader = new FileReader();} 79 | catch(err) {console.log("no support FileReader")} 80 | function tmpLoad() { 81 | bytesHandler && bytesHandler(thisRef,this.result); 82 | } 83 | reader.onload = tmpLoad; 84 | reader.readAsArrayBuffer(file); 85 | } 86 | function isWeixin(){ 87 | var ua = navigator.userAgent.toLowerCase(); 88 | if(ua.match(/MicroMessenger/i)=="micromessenger") { 89 | return true; 90 | } else { 91 | return false; 92 | } 93 | } 94 | /** 95 | * Created by shaoruiguo on 15/10/16. 96 | */ 97 | function selectImageWX(selectedFunc,thisValue) { 98 | selectedHandler = selectedFunc; 99 | thisRef = thisValue; 100 | wx.chooseImage({ 101 | count: 1, // 默认9 102 | sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 103 | sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 104 | success: function (res) { 105 | var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片 106 | //alert(localIds[0]); 107 | tmpCreateImage(localIds[0]); 108 | } 109 | }); 110 | } 111 | -------------------------------------------------------------------------------- /h5uploader_lib/bin/h5uploader/h5uploader.min.js: -------------------------------------------------------------------------------- 1 | function selectImage(e,t){selectedHandler=e,thisRef=t;var i=document.getElementById("fileInput");null==i&&(i=document.createElement("input"),i.id="fileInput",i.type="file",i.accept="image/*",i.style.height="0px",i.style.display="block",i.style.overflow="hidden",document.body.insertBefore(i,document.body.firstChild),i.addEventListener("change",tmpSelectFile,!1)),setTimeout(function(){i.click()},100)}function tmpSelectFile(e){var t=e.target.files[0],i=t.type;i||(i=mime[t.name.match(/\.([^\.]+)$/i)[1]]);var n=myCreateObjectURL(t);tmpCreateImage&&tmpCreateImage(n,t);var a=document.getElementById("fileInput");a.value=""}function tmpCreateImage(e,t){var i=new Image;i.onload=function(){var n=document.createElement("canvas");if(!isWeixin()&&i.height>MAX_HEIGHT){i.width*=MAX_HEIGHT/i.height,i.height=MAX_HEIGHT;var a=n.getContext("2d");a.clearRect(0,0,n.width,n.height),n.width=i.width,n.height=i.height,a.drawImage(i,0,0,i.width,i.height);var r=n.toDataURL("image/png")}else r=e;i.width=i.height=1,selectedHandler&selectedHandler(thisRef,r,t)},i.src=e,i.style.visibility="hidden",document.body.appendChild(i)}function myCreateObjectURL(e){return void 0!=window.URL?window.URL.createObjectURL(e):window.webkitURL.createObjectURL(e)}function myResolveObjectURL(e){void 0!=window.URL?window.URL.revokeObjectURL(e):window.webkitURL.revokeObjectURL(e)}function getImageData(e,t,i){function n(){bytesHandler&&bytesHandler(thisRef,this.result)}bytesHandler=t,thisRef=i;try{var a=new FileReader}catch(r){console.log("no support FileReader")}a.onload=n,a.readAsArrayBuffer(e)}function isWeixin(){var e=navigator.userAgent.toLowerCase();return"micromessenger"==e.match(/MicroMessenger/i)?!0:!1}function selectImageWX(e,t){selectedHandler=e,thisRef=t,wx.chooseImage({count:1,sizeType:["original","compressed"],sourceType:["album","camera"],success:function(e){var t=e.localIds;tmpCreateImage(t[0])}})}var mime={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",bmp:"image/bmp"},selectedHandler,bytesHandler,thisRef,MAX_HEIGHT=300; -------------------------------------------------------------------------------- /h5uploader_lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egret", 3 | "version": "2.5.1", 4 | "modules": [ 5 | { 6 | "name": "h5uploader", 7 | "description": "h5uploader", 8 | "files": ["h5uploader.js","wxuploader.js","h5uploader.d.ts"], 9 | "root": "src" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /h5uploader_lib/src/h5uploader.d.ts: -------------------------------------------------------------------------------- 1 | declare function selectImage(selectedHandler:Function,thisRef:any): void; 2 | declare function selectImageWX(selectedHandler:Function,thisRef:any): void; 3 | declare function getImageData(file:Blob,bytesHandler:Function,thisRef:any): void; 4 | declare function isWeixin():boolean; -------------------------------------------------------------------------------- /h5uploader_lib/src/h5uploader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shaoruiguo on 15/6/13. 3 | */ 4 | var mime = {'png': 'image/png', 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'bmp': 'image/bmp'}; 5 | var selectedHandler; 6 | var bytesHandler; 7 | var thisRef; 8 | var MAX_HEIGHT = 300; 9 | function selectImage(selectedFunc,thisValue) { 10 | selectedHandler = selectedFunc; 11 | thisRef = thisValue; 12 | var fileInput = document.getElementById("fileInput"); 13 | if(fileInput==null){ 14 | fileInput = document.createElement("input"); 15 | fileInput.id = "fileInput"; 16 | fileInput.type = "file"; 17 | fileInput.accept = "image/*"; 18 | fileInput.style.height = "0px"; 19 | fileInput.style.display = "block"; 20 | fileInput.style.overflow = "hidden"; 21 | document.body.insertBefore(fileInput,document.body.firstChild); 22 | fileInput.addEventListener('change', tmpSelectFile, false); 23 | } 24 | setTimeout(function(){fileInput.click()},100); 25 | } 26 | function tmpSelectFile(evt) { 27 | //console.log("image selected..."); 28 | var file = evt.target.files[0]; 29 | var type = file.type; 30 | if (!type) { 31 | type = mime[file.name.match(/\.([^\.]+)$/i)[1]]; 32 | } 33 | var ret = myCreateObjectURL(file); 34 | tmpCreateImage && tmpCreateImage(ret,file); 35 | var fileInput = document.getElementById("fileInput"); 36 | fileInput.value=""; 37 | } 38 | function tmpCreateImage(uri,file) { 39 | var image = new Image(); 40 | image.onload = function(){ 41 | var canvas = document.createElement("canvas"); 42 | if(!isWeixin() && image.height > MAX_HEIGHT) { 43 | //宽度等比例缩放 44 | image.width *= MAX_HEIGHT / image.height; 45 | image.height = MAX_HEIGHT; 46 | var ctx = canvas.getContext("2d"); 47 | ctx.clearRect(0, 0, canvas.width, canvas.height); 48 | canvas.width = image.width; 49 | canvas.height = image.height; 50 | ctx.drawImage(image, 0, 0, image.width, image.height); 51 | var smallURL = canvas.toDataURL("image/png"); 52 | } else { 53 | smallURL = uri; 54 | } 55 | image.width = image.height = 1; 56 | selectedHandler & selectedHandler(thisRef,smallURL,file); 57 | } 58 | image.src = uri; 59 | image.style.visibility = "hidden"; 60 | document.body.appendChild(image); 61 | } 62 | function myCreateObjectURL(blob){ 63 | if(window.URL != undefined) 64 | return window['URL']['createObjectURL'](blob); 65 | else 66 | return window['webkitURL']['createObjectURL'](blob); 67 | } 68 | function myResolveObjectURL(blob){ 69 | if(window.URL != undefined) 70 | window['URL']['revokeObjectURL'](blob); 71 | else 72 | window['webkitURL']['revokeObjectURL'](blob); 73 | } 74 | 75 | function getImageData(file,bytesFunc,thisValue) { 76 | bytesHandler = bytesFunc; 77 | thisRef = thisValue; 78 | try{var reader = new FileReader();} 79 | catch(err) {console.log("no support FileReader")} 80 | function tmpLoad() { 81 | bytesHandler && bytesHandler(thisRef,this.result); 82 | } 83 | reader.onload = tmpLoad; 84 | reader.readAsArrayBuffer(file); 85 | } 86 | function isWeixin(){ 87 | var ua = navigator.userAgent.toLowerCase(); 88 | if(ua.match(/MicroMessenger/i)=="micromessenger") { 89 | return true; 90 | } else { 91 | return false; 92 | } 93 | } -------------------------------------------------------------------------------- /h5uploader_lib/src/wxuploader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shaoruiguo on 15/10/16. 3 | */ 4 | function selectImageWX(selectedFunc,thisValue) { 5 | selectedHandler = selectedFunc; 6 | thisRef = thisValue; 7 | wx.chooseImage({ 8 | count: 1, // 默认9 9 | sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 10 | sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 11 | success: function (res) { 12 | var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片 13 | //alert(localIds[0]); 14 | tmpCreateImage(localIds[0]); 15 | } 16 | }); 17 | } -------------------------------------------------------------------------------- /test/Main.ts: -------------------------------------------------------------------------------- 1 | class Main extends egret.DisplayObjectContainer { 2 | 3 | /** 4 | * 加载进度界面 5 | * Process interface loading 6 | */ 7 | private loadingView:LoadingUI; 8 | private icon:egret.Bitmap; 9 | 10 | public constructor() { 11 | super(); 12 | this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this); 13 | } 14 | 15 | private onAddToStage(event:egret.Event) { 16 | //设置加载进度界面 17 | //Config to load process interface 18 | var uiClass:any = egret.getDefinitionByName("LoadingUI"); 19 | //this.loadingView = new LoadingUI(); 20 | this.loadingView = new uiClass(); 21 | this.stage.addChild(this.loadingView); 22 | 23 | //初始化Resource资源加载库 24 | //initiate Resource loading library 25 | RES.addEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this); 26 | RES.loadConfig("resource/resource.json", "resource/"); 27 | } 28 | 29 | /** 30 | * 配置文件加载完成,开始预加载preload资源组。 31 | * configuration file loading is completed, start to pre-load the preload resource group 32 | */ 33 | private onConfigComplete(event:RES.ResourceEvent):void { 34 | RES.removeEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this); 35 | RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onResourceLoadComplete, this); 36 | RES.addEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR, this.onResourceLoadError, this); 37 | RES.addEventListener(RES.ResourceEvent.GROUP_PROGRESS, this.onResourceProgress, this); 38 | RES.loadGroup("preload"); 39 | } 40 | 41 | /** 42 | * preload资源组加载完成 43 | * Preload resource group is loaded 44 | */ 45 | private onResourceLoadComplete(event:RES.ResourceEvent):void { 46 | if (event.groupName == "preload") { 47 | this.stage.removeChild(this.loadingView); 48 | RES.removeEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onResourceLoadComplete, this); 49 | RES.removeEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR, this.onResourceLoadError, this); 50 | RES.removeEventListener(RES.ResourceEvent.GROUP_PROGRESS, this.onResourceProgress, this); 51 | this.createGameScene(); 52 | } 53 | } 54 | 55 | /** 56 | * 资源组加载出错 57 | * The resource group loading failed 58 | */ 59 | private onResourceLoadError(event:RES.ResourceEvent):void { 60 | //TODO 61 | console.warn("Group:" + event.groupName + " has failed to load"); 62 | //忽略加载失败的项目 63 | //Ignore the loading failed projects 64 | this.onResourceLoadComplete(event); 65 | } 66 | 67 | /** 68 | * preload资源组加载进度 69 | * Loading process of preload resource group 70 | */ 71 | private onResourceProgress(event:RES.ResourceEvent):void { 72 | if (event.groupName == "preload") { 73 | this.loadingView.setProgress(event.itemsLoaded, event.itemsTotal); 74 | } 75 | } 76 | 77 | /** 78 | * 创建游戏场景 79 | * Create a game scene 80 | */ 81 | private createGameScene():void { 82 | var stageW:number = this.stage.stageWidth; 83 | var stageH:number = this.stage.stageHeight; 84 | this.icon = this.createBitmapByName("btn"); 85 | this.icon.anchorOffsetX = this.icon.width/2; 86 | this.icon.anchorOffsetY = this.icon.height/2; 87 | this.icon.x = stageW / 2; 88 | this.icon.y = stageH / 2 - 60; 89 | this.icon.touchEnabled = true; 90 | this.addChild(this.icon); 91 | this.icon.addEventListener(egret.TouchEvent.TOUCH_TAP,this.doSelect,this); 92 | } 93 | private doSelect(evt:egret.TouchEvent):void { 94 | if(isWeixin()) 95 | selectImageWX(this.selectedHandler,this); 96 | else 97 | selectImage(this.selectedHandler,this); 98 | } 99 | private selectedHandler(thisRef:any,imgURL:string,file:Blob):void { 100 | //alert("img selected"+imgURL); 101 | RES.getResByUrl(imgURL,thisRef.compFunc,thisRef,RES.ResourceItem.TYPE_IMAGE); 102 | //getImageData(file,thisRef.bytesHandler,thisRef); 103 | } 104 | private bytesHandler(thisRef:any,imgBytes:ArrayBuffer):void { 105 | console.log("大图数据:"+imgBytes); 106 | } 107 | private compFunc(texture:egret.Texture):void { 108 | //alert("compFunc"+texture); 109 | var imgReview:egret.Bitmap = new egret.Bitmap(texture); 110 | imgReview.touchEnabled = true; 111 | imgReview.addEventListener(egret.TouchEvent.TOUCH_BEGIN,this.removeImgReview,this); 112 | this.addChild(imgReview); 113 | } 114 | private removeImgReview(evt:egret.TouchEvent):void { 115 | var imgReview:egret.Bitmap = evt.currentTarget; 116 | this.removeChild(imgReview); 117 | } 118 | 119 | /** 120 | * 根据name关键字创建一个Bitmap对象。name属性请参考resources/resource.json配置文件的内容。 121 | * Create a Bitmap object according to name keyword.As for the property of name please refer to the configuration file of resources/resource.json. 122 | */ 123 | private createBitmapByName(name:string):egret.Bitmap { 124 | var result:egret.Bitmap = new egret.Bitmap(); 125 | var texture:egret.Texture = RES.getRes(name); 126 | result.texture = texture; 127 | return result; 128 | } 129 | 130 | } 131 | 132 | 133 | --------------------------------------------------------------------------------