我必须将Image urls转换为base64编码的字符串(因为this)
import { Pipe, PipeTransform } from '@angular/core';
declare var base64;
@Pipe({
name: 'tobase64'
})
export class Tobase64Pipe implements PipeTransform {
transform(value: any, args?: any): any {
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.open('GET', value, true);
xmlHTTP.responseType = 'arraybuffer';
xmlHTTP.onload = (e) => {
console.log('e',e);
var arr = new Uint8Array(e.currentTarget.response);
var raw = String.fromCharCode.apply(null, arr);
var b64 = base64.encode(raw);
var dataURL = "data:image/png;base64," + b64;
return dataURL;
};
xmlHTTP.send();
return null;
}
}
HTML
<image x="0" y="0" width="500" height="500" [attr.xlink:href]="'assets/hand.jpg' | tobase64" mask="url(#hole)" />
错误:
ERROR RangeError: Maximum call stack size exceeded
答案 0 :(得分:2)
从管道发出HTTP请求是完全可以的。在你的情况下,你最终只会做一个。请考虑这一点:如果将src
的{{1}}属性绑定到可以动态更改的属性,则最终会在属性更改时进行服务器调用;无论该呼叫是XHR呼叫还是对图像的简单请求,这都不是什么大问题。我对管道不太了解的唯一两件事是:
img
?看来,即使你没有得到任何错误,你仍然不会得到结果此解决方案需要清除两个管道:一个是用于进行XHR调用的自定义管道,另一个是Angular的内置管道null
。这是我们的自定义管道:
async
这就是你的HTML:
import { Pipe, PipeTransform } from '@angular/core';
import { Http, RequestOptions, Headers, ResponseContentType } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
@Pipe({name: 'toBase64'})
export class ImagePipe implements PipeTransform {
constructor(private http: Http) {}
transform(url: string) {
const headers = new Headers({'Content-Type': 'image/*'}); /* tell that XHR is going to receive an image as response, so it can be then converted to blob */
return this.http.get(url, new RequestOptions({headers: headers, responseType: ResponseContentType.Blob})) // specify that response should be treated as blob data
.map(response => response.blob()) // take the blob
.switchMap(blob => {
// return new observable which emits a base64 string when blob is converted to base64
return Observable.create(observer => {
const reader = new FileReader();
reader.readAsDataURL(blob); // convert blob to base64
reader.onloadend = function() {
observer.next(reader.result); // emit the base64 string result
}
});
});
}
}
我们使用我们的管道来获取base64字符串的可观察性,并使用<image x="0" y="0" width="500" height="500" [attr.xlink:href]="('assets/hand.jpg' | toBase64) | async" mask="url(#hole)" />
将实际发出的字符串插入async
标记内。
您需要记住的一件事是CORS:您的图像服务器应配置为接受XHR调用来运行Angular应用程序所在域的图像,同样,您必须提供绝对URL到自定义管道,否则它将向Angular应用程序的域本身发出请求。但在你的情况下,我假设你从你自己的应用程序提供图像,所以这不应该是一个问题。