Contexxt:我目前正在开发一个使用Angular构建的Web应用程序,其中包含用Silex编写的API。
我遇到以下情况:
很好,我想,我制作了API,因此它返回了base64编码的图像。很容易。将这个base64编码的数据设置为图像源更简单:src = "data:image/jpeg;base64," + response;
。这是使用ngSrc
完成的,这使它变得异步。灯箱使用锚标签的href
加载图像(我使用Colorbox),因此每张照片我有两个相当大的base64-dataURL。
我已经通过创建一个自定义Silex控制器为此创建了一个临时解决方法,该控制器不会从标头读取标记,而是从查询字符串读取标记。这允许我将图像源设置为:src = "http://api/img/1?token=" + token;
。数据网址及其内存饥饿问题已经一去不复返了。
但是,将来API很可能会开始要求HTTP基本身份验证来获取图像。并且基本身份验证凭据无法通过查询字符串传递。它们需要标题才能运行。所以我的解决方法将不再适用。因此,这是一个真正的临时解决方法。
我不完全确定如何解决这个问题。需要通过Ajax调用加载图像才能添加自定义标头。整个事情必须是异步的,所以加载尽可能快。加载图像后,无论显示多少图像,都不应占用内存,或者至少不要占用页面效果。
我一直在寻找将基于base64的图像加载到canvas
- 元素上。像这样:
$scope.loadThumbnails = function() {
$scope.photos.forEach(function($photo){
$photo.canvas_th = document.querySelector('canvas#' + $photo.id + '_th');
var request = $http({
method: "GET",
url: [URL]
});
var fetchThumbnailSuccess = function(response) {
console.debug("Fetched thumbnail with id " + $photo.id);
// Get drawing context
var ctx = $photo.canvas_th.getContext("2d");
// Create image with onload drawing to context
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
}
// Add data to image object, triggering the onload function which in turn draws the image to the context
img.src = 'data:image/jpeg;base64,' + response;
}
request.success(fetchThumbnailSuccess);
var fetchThumbnailFailure = function(response) {
console.error("Failed fetching thumbnail with id " + $photo.id);
console.debug(response);
}
request.error(fetchThumbnailFailure);
});
}
但我不确定这是否会保持更高性能。但我确信其他人必须先应对这种情况。我忽略了什么吗?做错了什么?我很想得到一些帮助,因为我目前仍然坚持使用我那不那么花哨的解决方法......任何人?
答案 0 :(得分:1)
Canvas使用尽可能多的内存来显示图像作为img元素,因此使用canvas不会对你的内存问题有所帮助。
只要您正在累积已编码的网址来存储图像数据,就会遇到不断增加的内存需求。
鉴于您当前灯箱的局限性,也许“滚动自己的灯箱”会给您带来更好的性能。
如何为初始显示提供thumnails,然后将单个完整大小的img元素的.src
属性更改为所选缩略图的URL。
这样你就只占用缩略图显示的内存和一个完整大小的图像。让浏览器缓存完整大小的图像,这样如果您的用户重新查看以前的完整大小的图像,它将从缓存中快速获取而不是重新下载。