Search code examples
angularamazon-s3file-storagesignaturepad

How to save Angular signaturePad blob to AWS S3 using flask


I am using the signaturePad and converting the base64 file to blob. From here i upload it onto s3 but when I download the file it's corrupted. I don't have any issues generating and uploading the file but when I downloaded the image from s3 I can not open it on my local drive. What I am I doing wrong?

This is my code

   drawSignature() {
        if (this.signaturePad.isEmpty()) {
          alert('Please provide a signature first')
        } else {
          const base64 = this.signaturePad.toDataURL('image/png', 0.5);
          const blob = this.base64toBlob(base64);
          const fd = new FormData();
          fd.append('image', blob);
          this.registrationService.saveSignatureRequest(fd)
            .subscribe(() => this.registrationService.successMessage(), 
(error) => this.formError = error['error'][0])
        }
      }


  base64toBlob(base64: string) {
    let sliceSize = 512;
    const byteString = atob(base64.split(',')[1]);
    const contentType = base64.split(',')[0].split(';')[0].split(':')[1];
    var byteArrays = [];
    for (var offset = 0; offset < byteString.length; offset += sliceSize) {
      var slice = byteString.slice(offset, offset + sliceSize);
      const byteNumber = new Array(slice.length);
      for (let i = 0; i < byteNumber.length; i++) {
        byteNumber[i] = byteString.charAt(i);
      }
      var byteArray = new Uint8Array(byteNumber);
      byteArrays.push(byteArray);
    }
    var blob = new Blob(byteArrays, { type: contentType });
    return blob;
  }

Function to upload file into S3

   def save_signature(self, file, object_name=None):
        filename = str(file)
        with current_app.app_context():
            from application.app import create_app
            app = create_app(current_app.config['DEV'])
            s3 = boto3.client(
                "s3",
                aws_access_key_id=app.config['AWS_ACCESS_KEY_ID'],
                aws_secret_access_key=app.config['AWS_SECRET_ACCESS_KEY']
            )
            bucket = app.config['S3_LOCATION']
            bucket_resource = s3
            try:
                file_storage_keys = [
                    file_key for file_key in object_name.keys()]
                if file_storage_keys:
                    file_storage_keys = file_storage_keys[0]
                else:
                    return
                file_storage = object_name[file_storage_keys]

                bucket_resource.put_object(Body=file_storage,
                                           Bucket=bucket,
                                           Key=filename+'.png',
                                           ContentType='image/png',
                                           ContentEncoding='utf-8')
            except ClientError as e:
                logging.error(e)
                return False
            return True

Solution

  • Try changing your base-64 to blob method to :-

    base64toBlob(b64Data) {
      const byteCharacters = atob(b64Data);
      const byteArrays = [];
      let sliceSize = 512;
      const contentType = base64.split(',')[0].split(';')[0].split(':')[1];
    
      for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        const slice = byteCharacters.slice(offset, offset + sliceSize);
    
        const byteNumbers = new Array(slice.length);
        for (let i = 0; i < slice.length; i++) {
          byteNumbers[i] = slice.charCodeAt(i);
        }
    
        const byteArray = new Uint8Array(byteNumbers);
        byteArrays.push(byteArray);
      }
    
      const blob = new Blob(byteArrays, {type: contentType});
      return blob;
    }