丈夫欲遂平生志,一载寒窗一举汤。这篇文章主要讲述[记录点滴]在Ionic和Android中上传Blob图片相关的知识,希望能为你提供帮助。
[记录点滴]在Ionic和android中上传Blob图片目录
- [记录点滴]在Ionic和Android中上传Blob图片
- 0x00 摘要
- 0x01 Blob
- 0x02 项目简述
- 0x02 Ionic
- 0x03 Android
- 0x04 Lua
- 0x05 参考
0x00 摘要本文是开发中的简略记录,具体涉及知识点有:Blob,Ionic,Android和Lua。
起因是因为刚刚看到一篇关于Blob的文章你不知道的 Blob ,突然回忆起来在开发过程中也曾经使用过这种图片,所以就翻了翻代码,整理记录下来。
0x01 BlobBlob(Binary Large Object)表示二进制类型的大对象,通常是影像、声音或多媒体文件。mysql/Oracle数据库中,就有一种Blob类型,专门存放二进制数据。
在 javascript 中 Blob 对象表示一个不可变、原始数据的类文件对象,它不一定非得是大量数据,也可以表示一个小型文件的内容。另外,javaScript 中的 File 接口是基于 Blob,继承 Blob 的功能并将其扩展使其支持用户系统上的文件。
Blob 由一个可选字符串 type 和 blobParts 组成,其中, type 通常为 MIME 类型。
MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,常见有:超文本标记语言文本 .html text/html 、PNG图像 .png image/png 、普通文本 .txt text/plain等。0x02 项目简述项目涉及方面比较多,有Ionic,Android,ios,后台处理图片部分是Lua。客户端需要上传小图片到后台。因为ios中上传图片这部分我没有参与,所以略过。
以下代码做了简略和转换。
0x02 IonicIonic上传过程中,主要使用Promise做异步控制,用$http做上传处理。
function uploadPicture(file) {
var q = $q.defer();
var url = .....;
var data = https://www.songbingjia.com/android/new FormData();
var ext = file.split(‘,‘)[0].split(‘:‘)[1].split(‘;
‘)[0].split(‘/‘)[1];
data.append("
file"
, dataURItoBlob(file), "
picture."
+ ext);
// 调了半天原来是这里Blob要加个name
$http.post(url, data, {
params: {
token: getToken()
},
transformRequest: angular.identity,
headers: {
‘Content-Type‘: undefined
}
})
.success(function(result) {
q.resolve(result);
})
.error(function(err) {
q.reject(err);
});
return q.promise;
}
base64字符串转图片格式的函数在这里
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(‘,‘)[0].indexOf(‘base64‘) >
= 0)
byteString = atob(dataURI.split(‘,‘)[1]);
else
byteString = unescape(dataURI.split(‘,‘)[1]);
// separate out the mime component
var mimeString = dataURI.split(‘,‘)[0].split(‘:‘)[1].split(‘;
‘)[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0;
i <
byteString.length;
i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {
name: ‘picture‘,
type: mimeString
});
}
0x03 Android网络传输使用了retrofit2。
public void uploadAvatar(Observer<
Response>
observer, int userId, String filePath) {
checkOauth();
File file = new File(filePath);
RequestBody requestBody = RequestBody.create(MediaType.parse("
image/*"
), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("
file"
, file.getName(), requestBody);
networkService.uploadAvatar(userId, body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
}// 这里是NetworkService实现
@Multipart
@POST(Constants.Url + "
{id}"
)
Observable<
Response>
uploadAvatar(@Path("
id"
) int id, @Part MultipartBody.Part file);
0x04 Lua后台中图片接口是用Lua来处理。
res, err = REQUEST.get_upload_file()
if _.isEmpty(res) then
ngx.say(RESPONSE.error(-1, err, 404))
end
当时参考了解决nginx + lua 上传文件问题。对原文代码做了修改以匹配我们实际环境。
-- 注意lua-resty-upload模块只能上传有boundary的post请求体,没有boundary的话需要使用socket来进行传输。
local UPLOAD = require "
resty.upload"
function _M.get_upload_file()
local chunk_size = 4096--如果不设置默认是4096.
local form,err = UPLOAD:new(chunk_size)
local sha1 = RESTY_SHA1:new()--测试时可以用来verify
local file
local filelen=0
local filename
local osfilepath = CONF.const()[‘UPLOAD_FILE_PATH‘]
local i=0
local response if not _.isEmpty(err) then
ngx.log(LOGGER.e("
form is: "
, form, "
, err is: "
, err))
endform:set_timeout(0) -- form:set_timeout(1000) -- 1 secwhile true do
local typ, res, err = form:read()
if not typ then
ngx.log(LOGGER.e("
failed to read: "
, err))
return false
endif typ == "
header"
then
if res[1] ~= "
Content-Type"
and res[1] ~= "
Content-Length"
then -- 对比原文增加了一个判断
filename = get_filename(res[2])
if filename then
i=i+1
filepath = osfilepath .. filename
file = io.open(filepath,"
wb+"
) -- 对比原文增加了b
if not file then
ngx.log(LOGGER.e("
failed to open file "
))
return false
end
else
end
end
elseif typ == "
body"
then
if file then
filelen= filelen + tonumber(string.len(res))
file:write(res)
sha1:update(res) -- verify in dev env
else
end
elseif typ == "
part_end"
then
if file then
file:close()
file = nil
ngx.say("
file upload success"
)
local sha1_sum = sha1:final() -- verify in dev env
sha1:reset()
end
elseif typ == "
eof"
then
break
else
-- do nothing
end
end
if i==0 then
ngx.log(LOGGER.e("
please upload at least one file!"
))
return false
endresponse = {
result = true,
fn = filename,
fp = filepath
}
return response
end
0x05 参考你不知道的 Blob
【[记录点滴]在Ionic和Android中上传Blob图片】解决nginx + lua 上传文件问题
推荐阅读
- android开发-java
- 基于Android 班费管理App的设计与实现
- 基于OpenCV 图像处理的Android 找茬App 设计与实现
- asp.net html静态文件没有触发global.asax中的Application_BeginRequest事件的解决方法
- P5709 深基2.习6Apples Prologue 题解
- 区分 BeanFactory 和 ApplicationContext?
- 安卓cpu调速器无任务状态测评
- 如何处理WinXP因配额不足导致无法访问的问题
- WinXP正确关闭防火墙的办法