感谢论坛高手们的帖子启发,我在参考SimpleFileStore的基础上,实现了用户头像照片的拍照、上传与显示,现分享如下:
1、拍照
调用手机拍照用的是cordova插件,所以在你需要拍照的页面中,首先要引用如下代码:
require("$UI/system/lib/cordova/cordova");
require("cordova!cordova-plugin-camera");
然后是调用相机拍照的函数,我是放在button的click事件中进行的:
Model.prototype.takePicBtnClick = function(event){
if(!navigator.camera){
return;
}
var self = this;
navigator.camera.getPicture(onLoadImageSuccess, onLoadImageFail, {
destinationType:navigator.camera.DestinationType.DATA_URL,
allowEdit:true,
quality:80,
targetWidth:100,
targetHeight:100,
saveToPhotoAlbum:true
});
//拍照成功后回调
function onLoadImageSuccess(imageData){
localStorage.setItem("imageData","data:image/jpeg;base64,"+imageData);
var smallImage = document.getElementById(self.getIDByXID('image1'));
//显示图像
smallImage.style.display = 'block';
smallImage.src = "data:image/jpeg;base64,"+imageData;
//图片上传
self.uploadPic(imageData);
}
function onLoadImageFail(error){
alert(error);
}
};
再然后是图片的上传:
//调用bass实现图片上传
Model.prototype.uploadPic = function(imageData){
//用户信息,用于上传图片后保存图片链接fImage
var userid = this._UserID; //this._UserID是自己定义的变量,在页面打开时被初始化
var userBaasData = this.comp("userBaasData");
var storeFileName = "";
var imageJson = {};
storeFileName = justep.UUID.createUUID();
justep.Baas.sendRequest({
"url" : "/summer/classes", //baas目录,请根据自己的配置进行修改
"action" : "uploadPicfile",
"async" : false,
"params" : {
"picData" : imageData,
"ownerID" : userid,
"storeFileName" : storeFileName
},
"success" : function(data) {
justep.Util.hint("图片上传成功");
//修改数据库中的图片链接 这里我的字段名叫fImage,可以根据自己的字段名修改
userBaasData.setFilter("Idfilter", "fID='"+userid+"'");
userBaasData.refreshData();
if(userBaasData.getCount()>0){
var fImage = '{"ownerID":"'+userid+'","storeFileName":"'+storeFileName+'"}';
userBaasData.setValue("fImage", fImage);
userBaasData.saveData();
}
}
});
};
然后是,后台对应的图片上传baas,将图片保存在UI2/myClassmate/uploadfiles目录下,这里可以自己进行调整:
public static JSONObject uploadPicfile(JSONObject params, ActionContext context) throws SQLException, NamingException, IOException {
System.out.println("uploadPicfile is running...");
String ownerID = params.getString("ownerID");
String storeFileName = params.getString("storeFileName");
String picData = params.getString("picData");
String baasPath = Thread.currentThread().getContextClassLoader().getResource("").getPath() ;
String docStorePath = baasPath + ".." + File.separator + ".."+ File.separator + "model" +File.separator + "UI2" +File.separator + "myClassmate" +File.separator+"uploadfiles" ;
File docstoreDir = new File(docStorePath);
if(!(docstoreDir.exists() && docstoreDir.isDirectory())){
docstoreDir.mkdirs();
}
String storePath = docStorePath + File.separator + ownerID;
File storeDir = new File(storePath);
if(!(storeDir.exists() && storeDir.isDirectory())){
storeDir.mkdirs();
}
System.out.println("后台计算的baasPath的值:"+ baasPath);
System.out.println("后台计算的docStorePath的值:"+ docStorePath);
System.out.println("后台计算的storeDir的值:"+ storeDir);
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] decodedBytes = decoder.decodeBuffer(picData);
String imgFile = storePath + File.separator + storeFileName;
FileOutputStream out = new FileOutputStream(imgFile);
out.write(decodedBytes);
out.close();
System.out.println("图片上传成功!");
} catch (Exception e) {
System.out.println("图片上传失败!");
e.printStackTrace();
}
return null;
}
2 选择照片
选择照片只能从相册中选,跟拍照比,只是在调用corvoda插件是,一个参数不同。
//选择照片
Model.prototype.selPicBtnClick = function(event){
if(!navigator.camera){
return;
}
var self = this;
navigator.camera.getPicture(onSuccess, onFail, {
mediaType : 0,//只选择图片
quality:80,
allowEdit:true,
targetWidth:100,
targetHeight:100,
destinationType: navigator.camera.DestinationType.DATA_URL, sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY
//sourceType: navigator.camera.PictureSourceType.PhotoAlbum//在安卓中,这个参数会跳出拍照界面
});
function onSuccess(imageData) {
var smallImage = document.getElementById(self.getIDByXID('image1'));
smallImage.style.display = 'block';
smallImage.src = "data:image/jpeg;base64,"+imageData;
//图片上传
self.uploadPic(imageData);
}
function onFail(message) {
alert('Failed because: ' + message);
}
};
3 照片显示
页面被刷新时,照片要根据数据库中的链接,显示在图片的位置,参考外卖的案例,我在数据库中是这样保存fImage字段的:
{"ownerID":"U01","storeFileName":"C708594A6EE00001F11723001E2011CF"}
记录这张图片的主人ownerID,和名字stroreFileName,主人用来作为存储目录,名字就是一个没有后缀名的文件。
要把这些信息解析成后台对应的文件,就需要另外定义一个函数:
//显示用户头像,自定义
Model.prototype.transUrl = function(fImage) {
if(!fImage)
return null;
this.actionUrl = "/baas/summer/classes/browsePicfile";
var src = null;
if (fImage !== null && fImage !== "" && fImage !== "[]") {
var imageJson = eval("("+fImage+")");
var storeFileName = imageJson.storeFileName;
var ownerID = imageJson.ownerID;
var url = this.actionUrl + '?storeFileName=' + storeFileName + '&ownerID=' + ownerID ;
src = require.toUrl(url);
}
return src;
};
定义该函数后,将想要显示图片的image空间的属性 bind-attr-src 设为如下值:
$model.transUrl(userData.val('fImage'))
其中userData的字段fImage就是存有{"ownerID":"U01","storeFileName":"C708594A6EE00001F11723001E2011CF"}这样内容的字段。
显示图片调用的对后台baas如下:
//显示图片文件
private static final int BUFFER_SIZE = 32768 * 8;
public static JSONObject browsePicfile(JSONObject params, ActionContext context) throws SQLException, NamingException, IOException {
System.out.println("browsePicfile is running...");
HttpServletRequest request = (HttpServletRequest)context.get(ActionContext.REQUEST);
HttpServletResponse response = (HttpServletResponse)context.get(ActionContext.RESPONSE);
String baasPath = Thread.currentThread().getContextClassLoader().getResource("").getPath() ;
String docStorePath = baasPath + ".." + File.separator + ".."+ File.separator + "model" +File.separator + "UI2" +File.separator + "myClassmate" +File.separator+"uploadfiles" ;
String ownerID = request.getParameter("ownerID");
String storeFileName = request.getParameter("storeFileName");
File file = new File(docStorePath + File.separator +ownerID + File.separator + storeFileName);
FileInputStream fis = new FileInputStream(file);
response.setHeader("Cache-Control", "pre-check=0, post-check=0, max-age=0");
String fileNameKey = "filename";
response.addHeader("Content-Disposition", "inline; "+fileNameKey+"=\"" + storeFileName + "\"");
OutputStream os = response.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
try {
int read;
while ((read = fis.read(buffer)) != -1) {
os.write(buffer, 0, read);
}
} finally {
fis.close();
}
return null;
}
OK!以上代码经过打包模式1,和打包模式3的测试,均可正常执行,欢迎大家改写成自己的更强版本。