user9088454
user9088454

Reputation: 1122

How to convert Camera Image to blob in ionic 5?

I want to post multipart form data, for this, we can do like this:

let formData = new FormData()
formData.append('myfile', 'your blob')

this.http.post(url, formData)

But I don't know how to convert a camera image to the blob. I am using native camera plugin and here my code:

  cameraOptions: CameraOptions = {
    quality: 20,
    destinationType: this.camera.DestinationType.DATA_URL,
    encodingType: this.camera.EncodingType.JPEG,
    mediaType: this.camera.MediaType.PICTURE,
    sourceType: this.camera.PictureSourceType.PHOTOLIBRARY
  }

constructor(public camera: Camera){}

takePhoto() {
    return new Promise(resolve => {
      this.camera.getPicture(this.cameraOptions).then((imageData) => {
        resolve(imageData);
      }, (err) => {
        resolve(err);
      });
    });
  }

I tried this code for blob:

dataURLtoBlob(dataURL) {
    debugger;
    // convert base64/URLEncoded data component to raw binary data held in a string
    let byteString: string;
    if (dataURL.split(',')[0].indexOf('base64') >= 0) {
      byteString = atob(dataURL.split(',')[1]);
    } else {
      byteString = unescape(dataURL.split(',')[1]);
    }
    // separate out the mime component
    let mimeString = dataURL
      .split(',')[0]
      .split(':')[1]
      .split(';')[0];

    // write the bytes of the string to a typed array
    let ia = new Uint8Array(byteString.length);
    for (let i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
    }

    let blobImg = new Blob([ia], { type: mimeString });
    console.log(blobImg);
    this.blobImage = blobImg;
}

With this code, I am able to get image data but how to convert in a blob, please help...

Hello @sergey-rudenko here my output

getPicture output:

imageDataURI:  content://com.android.providers.media.documents/document/image%3A78702

this.file.resolveLocalFilesystemUrl output:

entry:  

FileEntry {isFile: true, isDirectory: false, name: "image:78702", fullPath: "/com.android.providers.media.documents/document/image:78702", filesystem: FileSystem, …}
filesystem: FileSystem {name: "content", root: DirectoryEntry}
fullPath: "/com.android.providers.media.documents/document/image:78702"
isDirectory: false
isFile: true
name: "image:78702"
nativeURL: "content://com.android.providers.media.documents/document/image%3A78702"
__proto__: Entry

entry.file output:

file:  
File {name: "content", localURL: "cdvfile://localhost/content/com.android.providers.media.documents/document/image%3A78702", type: "image/jpeg", lastModified: 1588099237000, lastModifiedDate: 1588099237000, …}
end: 79807
lastModified: 1588099237000
lastModifiedDate: 1588099237000
localURL: "cdvfile://localhost/content/com.android.providers.media.documents/document/image%3A78702"
name: "content"
size: 79807
start: 0
type: "image/jpeg"
__proto__: Object

const blob output:

Blob {size: 79807, type: "image/jpeg"}
size: 79807
type: "image/jpeg"
__proto__: Blob

formData output:

FormData {}
__proto__: FormData
append: ƒ append()
  arguments: (...)
  caller: (...)
  length: 2
  name: "append"
  __proto__: ƒ ()
  [[Scopes]]: Scopes[0]
delete: ƒ delete()
entries: ƒ entries()
forEach: ƒ forEach()
get: ƒ ()
getAll: ƒ getAll()
has: ƒ has()
keys: ƒ keys()
set: ƒ ()
values: ƒ values()
constructor: ƒ FormData()
Symbol(Symbol.iterator): ƒ entries()
Symbol(Symbol.toStringTag): "FormData"
__proto__: Object

Upvotes: 2

Views: 3122

Answers (2)

Ritik Gupta
Ritik Gupta

Reputation: 1

<ion-col size="6">
        <ion-card class="imgBox" (click)="openCam(1)">
          <img *ngIf="imageSrc1 == undefined || imageSrc1 == null || imageSrc1.length <= 0" class="addImg"
            src="../../../assets/icon/photo.svg">
          <img *ngIf="imageSrc1 != undefined && imageSrc1 != null && imageSrc1.length > 0" class="camImg"
            src="{{imageSrc1}}">
        </ion-card>
      </ion-col>

      <ion-col size="6">
        <ion-card class="imgBox" (click)="openCam(2)">
          <img *ngIf="imageSrc2 == undefined || imageSrc2 == null || imageSrc2.length <= 0" class="addImg"
            src="../../../assets/icon/photo.svg">
          <img *ngIf="imageSrc2 != undefined && imageSrc2 != null && imageSrc2.length > 0" class="camImg"
            src="{{imageSrc2}}">
        </ion-card>
      </ion-col>

     openCam(id: number) {
    const options: CameraOptions = {
      quality: 100,
      destinationType: this.camera.DestinationType.NATIVE_URI,
      encodingType: this.camera.EncodingType.JPEG,
      mediaType: this.camera.MediaType.PICTURE,
      targetWidth: 300,
      targetHeight: 300,
    }
    this.camera.getPicture(options).then((imageData) => {
      if (id == 1) {
        this.imageSrc1 = (<any>window).Ionic.WebView.convertFileSrc(imageData);
      } else if (id == 2) {
        this.imageSrc2 = (<any>window).Ionic.WebView.convertFileSrc(imageData);
      }
      this.startUpload(imageData, id);
    }, (err) => {
      alert("error : " + JSON.stringify(err))
    });
  }
  

    startUpload(imageData: any, id: number) {
    this.file.resolveLocalFilesystemUrl(imageData)
      .then((entry) => {
        (<FileEntry>entry).file(file => this.read(file, id))
      })
      .catch(err => {
        alert('Error while reading image : ' + err.message);
      });
  }
  

    read(file: any, id: any) {
    const blob = new Blob([file], {
      type: file.type
    });
    console.log(blob);
    const formData = new FormData();
    formData.append('name', 'MyImageBlob');
    formData.append('file', blob, file.name);
    console.log("Form data", file.name);
    if (id == 1) {
      this.buyerdetails.Img1 = formData.get('file');
      if (this.buyerdetails.Img1 != null || undefined || 0 || '') {
        this.buyerdetails.IsImg1 = true;
      }
      console.log("img1", this.buyerdetails.Img1);
      console.log("formdata", formData.get('file'));
    }
    else if (id == 2) {
      this.buyerdetails.Img2 = formData.get('file');
      if (this.buyerdetails.Img2 != null || undefined || 0 || '') {
        this.buyerdetails.IsImg2 = true;
      }
      console.log("img1", this.buyerdetails.Img2);
      console.log("formdata", formData.get('file'));
    }
  }

Upvotes: 0

Sergey Rudenko
Sergey Rudenko

Reputation: 9235

In order to obtain the blob you need a few things:

First, make sure that the options of Camera plugin are set to return FILE_URI (URL to the binary file of the image):

options: CameraOptions = {
  quality: 100,
  destinationType: this.camera.DestinationType.FILE_URI, // set to FILE_URI
  encodingType: this.camera.EncodingType.JPEG,
  mediaType: this.camera.MediaType.PICTURE
};

Second, since FILE_URI is just a link and not actual file, you need a way to obtain it. You can do that using File plugin:

// Import it:

import {File, FileEntry} from '@ionic-native/file/ngx';

// Then use it in the method that Camera plugin has for taking pictures:

getPicture() {
  this.camera.getPicture(this.options).then((imageDataURI) => {
    this.file.resolveLocalFilesystemUrl(imageDataURI).then((entry: FileEntry) => 
    {
      entry.file(file => {
        console.log(file);
        this.readFile(file);
      });
    });
  }, (err) => {
    // Handle error
  });
};

Lastly to send it to your server, you need to read the file:

read(file) {
  const reader = new FileReader();
  reader.onload = () => {
    const blob = new Blob([reader.result], {
      type: file.type
    });
    const formData = new FormData();
    formData.append('name', 'MyImageBlob');
    formData.append('file', blob, file.name);
    this.service.upload(formData).subscribe(response => {
      console.log(response);
    });
  };
  reader.readAsArrayBuffer(file);
};

Let me know if you can take it from here.

Upvotes: 6

Related Questions