10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

monaca(phonegap)でcamera画像を取得して、画面遷移後、画像をサーバー(nifty mobile backend)にアップロードするまで。

Last updated at Posted at 2016-07-24

やりたいこと

1.ユーザー登録画面でカメラで画像(jpeg)を取得。imgタグに画像を設定。
2.ユーザー確認画面で、imgタグで表示。表示している画像をサーバー(nifty mobile backend)に登録。

※モバイルアプリでよくやることですが、「これだ!」というサンプルがなかったので :smile:

環境

1.monaca(Phone Gap)
2.nifty mobile backend
3.HTML5 FileAPI(Phone GapのFileAPIも参考になる)

注意

1.iOSのみ稼働確認しています。
2.作ったソースをバラして、コピペしたので、一部変なとこがあるかもしれません。

#説明
1.ユーザー登録画面からカメラ起動。このとき、カメラの属性で、「destinationType:Camera.DestinationType.FILE_URI」にします。
DATA_URIでもその画面内なら問題ないのですが、BASE64のデータとなるので、画面遷移すると、非常に重たくなります。

camera.js
function setOptions(srcType) {
  var options = {
      // Some common settings are 20, 50, and 100
      quality: 50,
      destinationType: Camera.DestinationType.FILE_URI,
      // In this app, dynamically set the picture source, Camera or photo gallery
      sourceType: srcType,
      encodingType: Camera.EncodingType.JPEG,
      mediaType: Camera.MediaType.PICTURE,
      allowEdit: true,
      correctOrientation: true,  //Corrects Android orientation quirks
      targetHeight : 100,
      targetWidth   :100
  }
  return options;
}
$scope.setPicture = function openFilePicker() {
  // ギャラリーの設定
  var srcType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
  var options = setOptions(srcType);
  // カメラを起動
  navigator.camera.getPicture(function cameraSuccess(imageUri) {
    console.log('albam success get image url:' + imageUri);
    // imgタグに設定する。
    var image = document.getElementById ('picture');
    image.src = imageUri;
    // Angularの場合は、一旦スコープに保存。
    $scope.picture = imageUri;
  }, function cameraError(error) {
      console.debug("Unable to obtain picture: " + error, "app");
  }, options);
}
$scope.submit = function() {
  if ($scope.userForm.$valid) {
   // Angularの場合は、locationのパラメータに設定。
    $location.search("username",$scope.username);
    $location.search("password",$scope.password);
    $location.search("password_confirm",$scope.password_confirm);
    $location.search("picture",$scope.picture);
    $scope.load("next.html");
  }
};

2.submit時に、window.resolveLocalFileSystemURL(HTML5 Web API)を使用して、ローカルファイルを取得します。nifty mobile backendに登録するには、blobにする必要があるので、FILE → FileReader.readAsArrayBufferで読み込んで、Blobを作成します。
(PhoneGapのwindow.resolveLocalFileSystemURLでも引数が異なるだけで、やることは多分一緒)

next.js
  // ローカルファイルを読み込んで、niftyにアップロードする。
  function addFile(imgUri) {
    return new Promise(function(resolve, reject) {
      window.resolveLocalFileSystemURL(imgUri, function success(fileEntry) {

        console.log("get file: " + fileEntry.fullPath);//実機でフルパス取れていない。
        var filename = fileEntry.name;

        fileEntry.file(function(file) {
          var reader = new FileReader();
          reader.onloadend = function(evt) {
            //readAsArrayBufferは非同期なので、ロード完了後のイベントで行う。
            console.log("Read complete!");

            // どうも、niftyの方で、blobにしないと、imageが読み込めないらしい。
            // fileでuploadすると、ダメ。色々試したが、Mobileで一番動きそうなのはこれ?
            var blob = new Blob([evt.target.result], {type: "application/octet-binary"});
            console.log("blob size:" + blob.size);
            ncmb.File.upload(filename, blob)
            .then(function(res){
              console.log("success upload !");
              resolve(res);
             })
            .catch(function(err){
              console.log("fail upload !");
              console.log(err);
              reject(err);
             });
          };
          reader.readAsArrayBuffer(file);
        }, function() {console.log(error);});
      }, function() {console.log(error);});
    });
  };

$scope.submit = function() {
  if ($scope.userForm.$valid) {
      // カメラからDATA_URL(base64)で取得するサンプルが沢山あるが、
      // DATA_URLだと、次画面への引き継ぎが重くなる。
      // また、niftyにあげるときに、blobにしないといけないくなるので、
      // FILE_URLで取得して、ローカルのファイルをblobにした方が無難。

      $scope.picture = imageUri;
      var addfile = addFile(imageUri);
      addfile.then(function(res){
        console.log("addFile Success");
        var response = res;
        console.log(response.fileName);
      });
      addfile.catch(function(err){
          console.log(err);
      });
  }
};

最後に。。技術要素が沢山あって、色々とハマってつかれた。。
つか、他にも参考になりそうなの沢山つくっているんだけどな。。
既に作ったソースからサンプル起こすの大変。。みんなどうしているんだろ。

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?