简体   繁体   English

使用Angular 2从图像URL获取base64图像

[英]get base64 image from image url using angular 2

I'm trying to display images that their URLs comes from Flickr photo search API. 我正在尝试显示其URL来自Flickr照片搜索API的图像。 I want to convert these image URLs to base64 so I can store the images in Session Storage and only call Flickr API if images do not exist in Session Storage: 我想将这些图像URL转换为base64,以便将图像存储在会话存储中,并且仅在会话存储中不存在图像时才调用Flickr API:

 export class AComponent { results: any[]; base64; constructor(private http: HttpClient, private jsonp: Jsonp, private router: Router, private storage: SessionStorageService) { if (!sessionStorage.getItem("results")) { this.http.get('https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=378060923d01ccb122bd53491163355d&tags=jungle&per_page=5&format=json&nojsoncallback=1').subscribe(data => { this.results = (<RootObject>data).photos.photo.map((photo) => { return { // url:`https://farm${photo.farm}.staticflickr.com/${photo.server}/${photo.id}_${photo.secret}_m.jpg`, base64: this.base64, // this line how can I get base64 image from the above url title: photo.title } }); sessionStorage.setItem("results", JSON.stringify(this.results)); }); } else { this.results = JSON.parse(sessionStorage.getItem("results")) } } } 

You should set responseType: ResponseContentType.Blob in your GET-Request settings, because so you can get your image as blob and convert it later da base64-encoded source. 您应该在GET-Request设置中设置responseType: ResponseContentType.Blob ,因为这样您就可以将图像获取为blob,并在以后将其转换为base64编码的源。 You code above is not good. 您上面的代码不好。 If you would like to do this correctly, then create separate service to get images from API. 如果您想正确执行此操作,请创建单独的服务以从API获取图像。 Beacuse it ism't good to call HTTP-Request in components. 因为在组件中调用HTTP请求不是很好。

Here is an working example: 这是一个工作示例:

Create image.service.ts and put following code: 创建image.service.ts并输入以下代码:

    getImage(imageUrl: string): Observable<File> {
        return this.http
            .get(imageUrl, { responseType: ResponseContentType.Blob })
            .map((res: Response) => res.blob());
    }

Now you need to create some function in your image.component.ts to get image and show it in html. 现在,您需要在image.component.ts创建一些函数以获取图像并将其显示为html。

For creating an image from Blob you need to use JavaScript's FileReader . 要从Blob创建图像,您需要使用JavaScript的FileReader Here is function which creates new FileReader and listen to FileReader's load-Event. 这是创建新FileReader并监听FileReader的load-Event的函数。 As result this function returns base64-encoded image, which you can use in img src-attribute: 结果,此函数返回base64编码的图像,您可以在img src-attribute中使用该图像:

imageToShow: any;

createImageFromBlob(image: Blob) {
       let reader = new FileReader();
       reader.addEventListener("load", () => {
          this.imageToShow = reader.result;
          // here you can save base64-image to session/localStorage
          localStorage.setItem('yourKey', this.imageToShow);
       }, false);

       if (image) {
          reader.readAsDataURL(image);
       }
}

In createIamgeFromBlob() -Function you can save your base64-image to sessionStorage/localStorage by key. createIamgeFromBlob() - createIamgeFromBlob() ,可以通过键将base64映像保存到sessionStorage / localStorage。 If the example above doesn't work, try to convert the result to string. 如果上面的示例不起作用,请尝试将结果转换为字符串。 For example: localStorage.setItem('yourKey', this.imageToShow.toString()); 例如: localStorage.setItem('yourKey', this.imageToShow.toString()); .

Now you should use your created ImageService to get image from api. 现在,您应该使用创建的ImageService从api获取图像。 You should to subscribe to data and give this data to createImageFromBlob -function. 您应该订阅数据并将此数据提供给createImageFromBlob -function。 Here is an example function: 这是一个示例函数:

getImageFromService() {
      this.isImageLoading = true;
      this.imageService.getImage(yourImageUrl).subscribe(data => {
        this.createImageFromBlob(data);
        this.isImageLoading = false;
      }, error => {
        this.isImageLoading = false;
        console.log(error);
      });
}

Now you can use your imageToShow -variable in HTML template like this: 现在,您可以像这样在HTML模板中使用imageToShow

<img [src]="imageToShow"
     alt="Place image title"
     *ngIf="!isImageLoading; else noImageFound">
<ng-template #noImageFound>
     <img src="fallbackImage.png" alt="Fallbackimage">
</ng-template>

I hope this description is clear to understand and you can use it in your project. 我希望此描述易于理解,并且可以在项目中使用。

loadImage(imageUrl) {
  const self = this;

  const xhr = new XMLHttpRequest()
  xhr.open("GET", imageUrl);
  xhr.responseType = "blob";
  xhr.send();
  xhr.addEventListener("load", function() {
      var reader = new FileReader();
      reader.readAsDataURL(xhr.response); 
      reader.addEventListener("loadend", function() {             
          self.base64Img = reader.result;
      });
  });
}

Link to plunker 链接到朋克

In order to get the plunker to work you need a cors valid imaged. 为了让the客工作,您需要一张带cors有效图像的图像。 I've used a chrome extension. 我使用了chrome扩展程序。

In the sample code I am storing the result in a component variable. 在示例代码中,我将结果存储在组件变量中。 The encoded 64 image is in reader.result. 编码的64图像位于reader.result中。

Answer taken from here 这里得到的答案

first you have to create Image url 首先,您必须创建图片网址

imgUrl = `https://farm${photo.farm}.staticflickr.com/${photo.server}/${photo.id}_${photo.secret}.jpg`

ref REF

then get the base64 image 然后获得base64图像

   function toDataURL(url, callback) {
          var xhr = new XMLHttpRequest();
          xhr.onload = function() {
            var reader = new FileReader();
            reader.onloadend = function() {
              callback(reader.result);
            }
            reader.readAsDataURL(xhr.response);
          };
          xhr.open('GET', url);
          xhr.responseType = 'blob';
          xhr.send();
        }

        toDataURL(imgUrl, function(dataUrl) {
          console.log('RESULT:', dataUrl)
        })

Final code 最终代码

export class AComponent {

results: any[];
base64;
constructor(private http: HttpClient, private jsonp: Jsonp, private router: Router,
    private storage: SessionStorageService) {

    if (!sessionStorage.getItem("results")) {

        this.http.get('https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=378060923d01ccb122bd53491163355d&tags=jungle&per_page=5&format=json&nojsoncallback=1').subscribe(data => {
            let promises = (<RootObject>data).photos.photo.map((photo) => {
                return this.getBase64Photo(photo).then(base64Photo => {
                      return base64Photo;
                })
            }
            Promise.all(promises)
              .then(results => {
                this.results = results;
              })
              .catch(e => {
                console.error(e);
              })
            sessionStorage.setItem("results", JSON.stringify(this.results));
        });
    }
    else {

        this.results = JSON.parse(sessionStorage.getItem("results"))
    }

}

toDataURL(url, callback) {
      var xhr = new XMLHttpRequest();
      xhr.onload = function() {
        var reader = new FileReader();
        reader.onloadend = function() {
          callback(reader.result);
        }
        reader.readAsDataURL(xhr.response);
      };
      xhr.open('GET', url);
      xhr.responseType = 'blob';
      xhr.send();
}

getBase64Photo(photo){
    return new Promise((resolve, reject) => {
        let url =`https://farm${photo.farm}.staticflickr.com/${photo.server}/${photo.id}_${photo.secret}_m.jpg`;
        let base64Data;
        this.toDataURL(url, (data)=>{
            resolve({
            base64: base64Data, // this line how can I get base64 image from the above url
            title: photo.title
            })
        })
      });
}

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM