14

I am struggling trying to convert a given image url to base64... in my case i have a String with the image's path

var imgUrl = `./assets/logoEmpresas/${empresa.logoUrl}`

how can i convert the given image url in a base64 directly?... i tried this post.

Converting an image to base64 in angular 2

but this post is getting the image from a form... how can i adapt it?

Sergio Cano
  • 690
  • 3
  • 13
  • 36

3 Answers3

18

You can use this to get base64 image

async function getBase64ImageFromUrl(imageUrl) {
  var res = await fetch(imageUrl);
  var blob = await res.blob();

  return new Promise((resolve, reject) => {
    var reader  = new FileReader();
    reader.addEventListener("load", function () {
        resolve(reader.result);
    }, false);

    reader.onerror = () => {
      return reject(this);
    };
    reader.readAsDataURL(blob);
  })
}

Then call it like this

getBase64ImageFromUrl('your url')
    .then(result => testImage.src = result)
    .catch(err => console.error(err));
Tony Ngo
  • 19,166
  • 4
  • 38
  • 60
2

works like charm in pdfMake and angular

You can use this function to create generate a base64 image

    toDataURL = async (url) => {
    console.log("Downloading image...");
    var res = await fetch(url);
    var blob = await res.blob();

    const result = await new Promise((resolve, reject) => {
      var reader = new FileReader();
      reader.addEventListener("load", function () {
        resolve(reader.result);
      }, false);

      reader.onerror = () => {
        return reject(this);
      };
      reader.readAsDataURL(blob);
    })

    return result
  };

and then call it like this

imageSrcString = await this.toDataURL(imageSrc)
2

If we're doing this in Angular, we may as well make use of HttpClient and a Service.

Let's go ahead and add the HttpClientModule into our related Module, we'll need this in order to use HttpClient.

@NgModule({
  imports: [HttpClientModule],
  ...
})
export class AppModule {}

Then let's create a generic Image Service, and then ask Angular to inject the HttpClient into our Service.

@Injectable()
export class ImageService {
  constructor(private http: HttpClient) { }
}

Once that's done we can actually create our function in our service

imageUrlToBase64(urL: string) {
  return this.http.get(urL, {
      observe: 'body',
      responseType: 'arraybuffer',
    })
    .pipe(
      take(1),
      map((arrayBuffer) =>
        btoa(
          Array.from(new Uint8Array(arrayBuffer))
          .map((b) => String.fromCharCode(b))
          .join('')
        )
      ),
    )
}

When we use http.get and provide arraybuffer as our response type, Angular interprets the body of our request as an ArrayBuffer. What that means is that we'll now have our image as an array of bytes. All we need to do is then convert our ArrayBuffer to a base64 string. If you'd like to view alternative options, this SO Question has good answers.

// taken from above
map(
  btoa(
    Array.from(new Uint8Array(arrayBuffer))
    .map((b) => String.fromCharCode(b))
    .join('')
  )
)

Now that the function is done, we can shift to usage:

@Component()
export class AppComponent {
  base64Image: string;
  constructor(private imageService: ImageService) {
      this.imageService.imageUrlToBase64('https://picsum.photos/200/300').subscribe(
          base64 => {
              this.base64Image = base64
      })
  }
}

We'll now have access to the image as a base64

Dane Brouwer
  • 2,827
  • 1
  • 22
  • 30
  • Hi, thanks for your answer... but it gives me an error, when i try with your URL it works but if try with any other URL it fails ( HttpErrorResponse in console ), what is happening? the url that im trying is... https://img-01.stickers.cloud/packs/0ba639f2-873a-447c-8f1d-80f6378523d0/webp/436e532a-8330-4bf3-a8cb-a5679eb0e9ed.webp Or... https://clientes.infowork.es/74042-thickbox_leomega/tpvtactil15bluebeej194gb64gbaluminio.jpg Any help is apreciated! – Sergio Cano Feb 22 '22 at 17:21
  • Are you prefixing your URL with `https://`? – Dane Brouwer Feb 23 '22 at 07:26
  • yep, i'm typing the url exactly how i copied here, very weird error... i finally decided to download and convert it in my node server... i think i can deal better with errors , but would be interesting to solve this error :S – Sergio Cano Feb 23 '22 at 10:27
  • You're probably running into a CORS error - that would be a whole other issue to solve! – Dane Brouwer Feb 23 '22 at 11:36