[记录点滴]在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 Blob

Blob(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 Ionic

Ionic上传过程中,主要使用Promise做异步控制,用$http做上传处理。

function uploadPicture(file) {      var q = $q.defer();      var url = .....;      var data = 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(Observerobserver, 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}")ObservableuploadAvatar(@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))    end    form:set_timeout(0) -- form:set_timeout(1000) -- 1 sec    while true do        local typ, res, err = form:read()                if not typ then            ngx.log(LOGGER.e("failed to read: ", err))            return false        end        if 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    end    response = {        result = true,         fn = filename,         fp = filepath    }    return responseend

0x05 参考

你不知道的 Blob

解决nginx + lua 上传文件问题

©著作权归作者所有:来自51CTO博客作者罗西的思考的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. Android(安卓)matrix 控制图片的旋转、缩放、移动
  2. android拍照与读取相册
  3. Android(安卓)报错:Caused by: android.os.FileUriExposedExcepti
  4. android解决坚屏拍照和保存图片旋转90度的问题,并兼容4.0
  5. [Android]在App中使用相机
  6. android WebView 图片缩放功能小结
  7. Android(安卓)主流图片库Picasso Glide Fresco对比分析
  8. android手机客户端上传文件,java servlet服务器端接收并保存到服
  9. android背景选择器selector用法汇总

随机推荐

  1. android后台进程隐藏手段
  2. ch026 Android Socket
  3. Uyghur Android
  4. android的布局练习
  5. Fragment 中的onConfigurationChanged 在
  6. android中重要的知识点
  7. android访问SD卡的权限
  8. android 选中效果xml文件
  9. android 设置主页面的方式
  10. Android渐变色xml文件