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