0

I have an ionic 3 app; I am working on upload profile picture functionality. In this, I want to select the image from either gallery or capture image using the camera. After that, I will have two images/image_paths. I want to upload these two images along with user_id, access_token

Select Image From Gallery let option = { title: 'Select Picture', message: 'Select Least 1 Picture', maximumImagesCount: 1, outType: 0 };

this.imagePicker.getPictures(option).then(results => {
          for (var i = 0; i < results.length; i++) {
            // alert('Image URI: ' + results[i]);
            this.imageSelected = "data:image/jpeg;base64," +results[i];
            // this.imageSelected = results[i];
            let option = {
              quality: 100,
              targetHeight: 400,
              targetWidth: 400,
            };
            this.crop.crop(this.imageSelected, option).then((data) => {
              this.imageCropped = "data:image/jpeg;base64," +data;
              // alert(this.imageCropped);
              this.saveProfileImage(this.imageSelected, this.imageCropped);
            }, err => {
              this.imageCropped = '';
              alert(err);
            });
          }
        }, err => {
          this.imageSelected = '';
          alert('Error' + err);
        })

Select an image from the camera let options: CameraOptions = { quality: 100, destinationType: this.camera.DestinationType.DATA_URL, encodingType: this.camera.EncodingType.JPEG, mediaType: this.camera.MediaType.PICTURE }

this.camera.getPicture(options).then((imageData) => {
          // alert(imageData);
          this.imageSelected = "data:image/jpeg;base64," +imageData;
          let option = {
            quality: 100,
            targetHeight: 400,
            targetWidth: 400,
          };
          this.crop.crop(this.imageSelected, option).then((data) => {
            this.imageCropped = "data:image/jpeg;base64," +data;
            this.saveProfileImage(this.imageSelected, this.imageCropped);
          }, err => {
            this.imageCropped = '';
            alert(err);
          });
        }, (err) => {
          this.imageSelected = '';
          alert('Error' + err);
        });

Please see the above code and if it is right, suggest me how to write upload function with either form data or any another method

[This is screenshot of first way i tried uploading images][1]

This is a screenshot of the second way I tried uploading images

8
  • please make sure that you need to upload file? and u create any function or not? Commented Mar 14, 2018 at 6:24
  • you want to send crop image to server or not? Commented Mar 14, 2018 at 6:38
  • @Utpaul yes i want to upload both images to server along with some data like user_id, access_token etc So that i will use both images cropped and full image in application as per suits. Commented Mar 14, 2018 at 6:49
  • crop as well a without crop data or only cropping image data Commented Mar 14, 2018 at 6:51
  • cropped image as well as uncropped image Commented Mar 14, 2018 at 6:57

2 Answers 2

4

Even I was facing the same problem some time back, and did not find proper solution on the web. Below is the solution, which I found after some research and works perfectly fine, not just for images, but also for other files. Since Question asked is about the images, I will explain the answer w.r.t to images. (Except choosing the files, the procedure remains same for other files).

  1. You can choose the image using the Cordova camera plugin, After installing the plugin and importing it on app.module.ts and adding it to provider, you can use below code to choose images from camera or from gallery. ActionSheetController would be the best way to give option to user, to pick image from gallery or from camera.

code for choosing the image from camera:

const options: CameraOptions = {
  quality: 100,
  correctOrientation: true,
  cameraDirection: 1,
}

this.camera.getPicture(options).then((imageData) => {
  console.log("IMAGE DATA IS", imageData);
}).catch(e => {
  console.log("Error while picking from camera", e)
})

code for choosing the image from gallery:

var options = {
  sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
  destinationType: this.camera.DestinationType.FILE_URI,
};
this.camera.getPicture(options).then((imageData) => {
  console.log("IMAGE DATA IS", imageData);
}).catch(e => {
  console.log("Error while picking from gallery", e)
});
  1. After choosing the image,you need to convert it to base64 using com-badrit-base64 plugin. After installing the plugin and importing it on app.module.ts and adding to provider list, Just pass the output of camera plugin to this, the chosen image will be converted into base64.

Below is the code snippet to convert the chosen image to base64,I have written it for camera, it remains same for gallery. After converting the image to base64 push it to an array. Now you are able to choose multiple images and store it's value in array.

var options = {
  sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
  destinationType: this.camera.DestinationType.FILE_URI,
};
this.camera.getPicture(options).then((imageData) => {
  console.log("IMAGE DATA IS", imageData);

  let filePath: string = imageData
  this.base64.encodeFile(filePath).then((base64File: string) => {
    console.log(base64File);
    this.base64File.push(base64File);
  }, (err) => {
    console.log(err);
  });

}).catch(e => {
  console.log("Error while picking from gallery", e)
});
  1. Now send the data to server via your API. You can use cordova-plugin-advanced-http or Angular-http to achieve it. The API should take images in the format of array, along with other parameters. As base64 images will be a string with bigger length, formData or row is recommended over the url-encoded format, for post method of REST.
  2. Now in back-end the body will be parsed and the image array will be extracted. In all the popular back-end languages(Java, PHP, NodeJS, C# etc), which are used for writing API's,there are free libraries to convert base64 image to actual image.
  3. Whola, that's it, now you are be able to send multiple images to your server via API. Along with images, if your trying to choose files of any other MIME type (pdf, doc, docx etc) you can use the same approach for it.

I have also created a git hub repository at: https://github.com/coolvasanth/upload-multiple-image-files-in-Ionic-3-4/blob/master/README.md

Sign up to request clarification or add additional context in comments.

Comments

1

First of all you need to create an formData object.

private formData:any = {
    'user_id':this.userId,
    'access_token':this.accessToken,
    'device_id':this.devId,
    'device_type':this.devType,
    'registration_ip':this.ipAdd,
    'image':'',
    'crop_image'
  };

Need to change imagePicker

this.imagePicker.getPictures(option).then(results => {

  for (var i = 0; i < results.length; i++) {
    // alert('Image URI: ' + results[i]);

    //set it results[i] in unCropImages

    this.data.image= "data:image/jpeg;base64," +results[i];

    this.imageSelected = results[i];
    let option = {
      quality: 100,
      targetHeight: 400,
      targetWidth: 400,
    };

    this.crop.crop(this.imageSelected, option).then((data) => {
      this.imageCropped = "data:image/jpeg;base64," +data;
      // alert(this.imageCropped);

      //set it imageCropped in cropImage

      this.data.crop_image= this.imageCropped;

      //No need to this function

      this.saveProfileImage();

    }, err => {
      this.imageCropped = '';
      alert(err);
    });
  }
}, err => {
  this.imageSelected = '';
  alert('Error' + err);
})

Need to change in camera

this.camera.getPicture(options).then((imageData) => {
          // alert(imageData);
          this.imageSelected = "data:image/jpeg;base64," +imageData;

          this.data.image= "data:image/jpeg;base64," +results[i];

          let option = {
            quality: 100,
            targetHeight: 400,
            targetWidth: 400,
          };
          this.crop.crop(this.imageSelected, option).then((data) => {
            this.imageCropped = "data:image/jpeg;base64," +data;

            this.data.crop_image= this.imageCropped;

          this.saveProfileImage();
          }, err => {
            this.imageCropped = '';
            alert(err);
          });
        }, (err) => {
          this.imageSelected = '';
          alert('Error' + err);
        });

Setup POST method

First of all you need to inject HttpClientModule in import section of app.module.ts file

Then inject private http: HttpClient inside constructor in saveProfileImage() funtion class

change in saveProfileImage()

saveProfileImage(){

  return new Promise((resolve, reject) => {
    this.http.post('Your URL', JSON.stringify(this.formData))
      .subscribe(res => {
        resolve(res);
       //success 
      }, (err) => {
        reject(err);
        //fail
      });
  });

}

6 Comments

Can you please go ahead and give me complete code upto post method with dummy url. Because i am confused with formData and fileTransfer. Used both but none is working as expected.
you have only four field or more than 4 field... if more then tell me...
one more question..Is it necessary to take array of unCropImages and cropImages in data object since we are sending one image in both. My back end asks for formData. So how i will send it. Please help me
if uncrop and crop image not more then one then we need not array ... please assure me uncrop have 1 image as well as crop image have only 1 image
please check above screen shots, it will help you to understand problem more clearly (i have edited question for screenshots)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.