使用PhantomJS中的FileReader将base64转换为Blob,将Blob转换为base64

时间:2014-11-05 14:04:33

标签: javascript blob phantomjs karma-runner filereader

我有角度控制器,它应该与图像一起使用。它在范围内有属性file的观察者。如果属性将包含文件数组,则FileReader应读取这些文件(仅第一个文件)并转换为base64字符串并添加到页面。像这样:

$scope.$watch('file', function (files) {
    if (files && files.length > 0) {
        if (files[0].type && files[0].type.match('image.*')) {
            var reader = new FileReader();
            reader.onload = function (e) {
                render(e.target.result);
            };
            reader.readAsDataURL(files[0]);
        }
    }
});

render功能:

function render (src) {
    var image = new Image();
    image.addEventListener('load', function () {
        if (image.width < MIN_SIZE || image.height < MIN_SIZE) {
            $scope.error = $filter('localize')('UploaderWindow_ImageSizeError');
            $scope.$apply();
        } else {
            new global.ICropper('original-image', {
                gap: 0,
                keepSquare: true,
                image: src,
                preview: ['cropped-image']
            });
        }
    });
    image.addEventListener('error', function () {
        $scope.error = $filter('localize')('UploaderWindow_SelectImage');
        $scope.$apply();
    });
    image.src = src;
};

ICropper应在img属性中使用base64在DOM中创建src元素。 问题是,我有这个功能的单元测试。测试用例:

it('Should render new image from file input', function () {
    var imageData = image.split(',')[1],
        imageType = image.split(',')[0].replace('data:', '').replace(';base64', ''),
        file = base64toBlob(imageData, imageType);

    expect(originalImage.lastElementChild).toBe(null);
    runs(function () {
        $scope.file = [file];
        $scope.$apply();
    });
    waitsFor(function () {
        return originalImage.lastElementChild;
    }, 'waiting_original_form');
    runs(function () {
        expect(originalImage.lastElementChild.src).toBe(image);
    });
});

变量image包含有效的base64字符串originalImage.lastElementChild - img元素,它应由ICropper创建。 base64toBlob函数的主体:

function base64toBlob (b64Data, contentType) {
    var binary = atob(b64Data.replace(/\s/g, '')),
        binaryLength = binary.length,
        buffer = new ArrayBuffer(binaryLength),
        view = new Uint8Array(buffer);

    for (var i = 0; i < binaryLength; i++) {
        view[i] = binary.charCodeAt(i);
    }

    return new Blob([view], {type: contentType});
}

此测试已在Chrome中成功通过,但未在PhantomJS中通过:

timeout: timed out after 5000 msec waiting for waiting_original_form

我认为,这是因为图像的加载事件未被触发,而是触发了错误。但我不明白为什么?我知道,Blob未在PhantomJS中定义,所以我使用此polyfill:https://github.com/eligrey/Blob.js

0 个答案:

没有答案