【问题标题】:ArrayBuffer to blob conversionArrayBuffer 到 blob 的转换
【发布时间】:2017-10-24 04:19:19
【问题描述】:

我有一个项目需要在浏览器中显示 djvu 架构。

我发现了这个旧的library on Github,据我所知,它将 djvu 文件转换为 bmp,然后将它们放入画布元素中。

正如我所说,图书馆很旧(上次提交是 5 年前),所以我需要做一些更正。主要问题是 lib 使用过时的 BlobBuilder。

我为解决这个问题而采取的步骤:

  1. 通过 Chrome DevTools 解压这个库
  2. 初始错误位于第 3774 行 var c = "undefined" != typeof MozBlobBuilder ? MozBlobBuilder : "undefined" != typeof WebKitBlobBuilder ? WebKitBlobBuilder : console.log("warning: cannot build blobs")
  3. 我注释掉了这一行
  4. 接下来,我注释掉了c = new c; 行以及下面的一些行。

所以,现在看起来是这样(变量 I 是数组缓冲区,而 ololo1 和 ololo2 是某种偏移和限制)

var c = new Blob(new Uint8Array(new Uint8Array(I,ololo1,ololo2)))
              , b = b.createObjectURL(c)
              , c = document.getElementById(kb)
              , f = c.getContext("2d")
              , h = new Image
              , g = a[Ea >> 2]
              , i = a[Fa >> 2]
              , j = c.width
              , k = Math.round(i * j / g);

            h.onload = function()
            {
                var a = g / j;
                4 < a && (a = 4);
                1 > a && (a = 1);
                f.globalAlpha = 1;

                for (N = 0; N < a; N++)
                    f.drawImage(h, N, N, g - a + N, i - a + N, 0, 0, j, k),
                    f.globalAlpha *= 1 - 1 / a;
                R(h.complete, "Image /bmp.bmp could not be decoded")
            }
            ;
            h.onerror = function(errorMsg, url, lineNumber, column, errorObj) {
                console.log(errorMsg, url, lineNumber, column, errorObj);
                console.log("Image /bmp.bmp could not be decoded!")
            }           
            ;

现在我遇到了错误“无法解码图像 /bmp.bmp!”(在 h.onerror 处理程序中抛出)。

所以,我的问题是:我做错了什么?

【问题讨论】:

  • 原来是c.append((new Uint8Array(new Uint8Array(I,ololo1,ololo2))).buffer)。我不明白为什么作者将他的 Uint8array 嵌套在一个新的里面......你应该可以只使用新的 Blob([new Uint8Array(I,ololo1,ololo2)]);
  • @Kaiido 非常感谢,就像一个魅力。您可以将其发布为答案吗?

标签: javascript djvu


【解决方案1】:

我不知道为什么作者确实将他的 Uint8Array 包装在一个新的...请注意,我并不真正了解已弃用的 BlobBuilder API,但我可以在您的代码中看到一个错字是您需要将你的 TypedArray 包装在一个普通的数组中:

new Blob([new Uint8Array(buffer, byteOffset, length)]);

Blob 构造函数将blobParts sequence 作为第一个参数,然后按此顺序搜索BufferSourceUSVStringsBlob 元素。所以当你传递一个 TypedArray 时,它实际上会遍历这个 TypedArray 的所有条目并将它们视为 USVString (从而将它们的数字Blob 中的 UTF-8 字符串的值)。这很少是你想要的,所以最好总是在这个构造函数中传递一个 Array

【讨论】:

  • 也节省了我的一天(我传入了一个 arrayBuffer 来处理二进制数据,但需要将其包装为数组)。但是,我认为 Uint8Array 应该不带括号传入,因为它已经是一个数组,因此不是 OP 的问题。您需要 ArrayBuffer 周围的括号。
  • @aamarks 不,如果你传递一个 Uint8Array,你会将它的所有 0~255 值保存为 utf8 字符串,因为 Blob 构造函数不会访问它 .buffer 属性并且它可能是想要的将包含的数据保存为二进制。
  • 我明白了,谢谢。似乎在 Uint8Array 视图所基于的缓冲区或 Uint8Array 中传递,只要其中一个在括号中,两者都可以工作。
  • Uint8Array 是一种浪费。你不需要它。只需new Blob([buffer])。 ArrayBuffer 是一个字节数组。
  • ^ 这只是一个视图。不确定起点是 ArrayBuffer 还是其他类型的视图?这可能会破坏 new Blob(...) 中的 blob 构建器
【解决方案2】:
var buffer = new ArrayBuffer(32);

new Blob([buffer]);

所以 Uint8Array 应该是

new Blob([new Uint8Array([1, 2, 3, 4]).buffer]);

【讨论】:

    猜你喜欢
    • 2013-02-26
    • 2021-08-24
    • 2020-09-22
    • 2013-07-17
    • 2017-02-28
    • 2018-04-09
    • 1970-01-01
    • 2011-12-08
    • 2015-10-12
    相关资源
    最近更新 更多