Modern Implementation and Common Issues of ArrayBuffer to Blob Conversion in JavaScript

Dec 01, 2025 · Programming · 13 views · 7.8

Keywords: JavaScript | ArrayBuffer | Blob Conversion | TypedArray | Binary Data Processing

Abstract: This article provides an in-depth exploration of modern methods for converting ArrayBuffer to Blob in JavaScript, focusing on the proper usage of the Blob constructor, the distinction between TypedArray and Array, and how to avoid common encoding errors. Through a practical DJVU file processing case, it explains how to fix outdated BlobBuilder code and offers complete implementation examples and best practice recommendations.

In modern web development, handling binary data is a common requirement, particularly when processing multimedia files such as images, audio, and video. JavaScript provides two important binary data representations: ArrayBuffer and Blob. The conversion between them frequently appears in scenarios like file processing and network transmission. This article explores the correct implementation of ArrayBuffer to Blob conversion based on a practical DJVU file processing case.

Case Background and Problem Analysis

While developing a project that required displaying DJVU schemas in a browser, a developer encountered issues with an outdated library. The library originally used the deprecated BlobBuilder API to convert DJVU files to BMP format and display them in a Canvas. Since BlobBuilder has been deprecated in modern browsers, the developer attempted to replace it with the standard Blob constructor but encountered image decoding errors during the conversion process.

The original problematic code snippet was:

var c = new Blob(new Uint8Array(new Uint8Array(I,ololo1,ololo2)))

This code attempts to create a Blob object but has two critical issues: first, it incorrectly nests two Uint8Array constructors; second, and more importantly, it fails to wrap the TypedArray in an Array before passing it to the Blob constructor.

Correct Usage of the Blob Constructor

The first parameter of the Blob constructor should be a blobParts sequence. According to the W3C FileAPI specification, this sequence can contain BufferSource, USVString, or Blob objects. When a TypedArray is passed directly, the Blob constructor iterates over each element of the TypedArray and converts numerical values to UTF-8 strings, which is typically not the desired behavior.

The correct approach is to wrap the TypedArray in a regular Array:

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

If slicing the ArrayBuffer is unnecessary, a more concise method is to pass the ArrayBuffer directly:

new Blob([buffer]);

Deep Understanding of BufferSource and TypedArray

ArrayBuffer is a low-level object in JavaScript that represents raw binary data but does not provide direct methods to access the data. TypedArrays (such as Uint8Array, Int16Array, etc.) are views that provide access to ArrayBuffer data. When creating a TypedArray, you can specify the source ArrayBuffer, byte offset, and length, allowing you to process only specific portions of the ArrayBuffer.

In the DJVU processing case, ololo1 and ololo2 likely represent the byte offset and data length, respectively, used to extract specific image data from the original ArrayBuffer. The correct implementation should look like this:

var bufferSlice = new Uint8Array(I, ololo1, ololo2);
var blob = new Blob([bufferSlice]);
var objectURL = URL.createObjectURL(blob);

Complete Fix Solution

Based on the above analysis, the complete fixed code should be as follows:

// Create a Uint8Array view to access a specific portion of the ArrayBuffer
var uint8Array = new Uint8Array(I, ololo1, ololo2);

// Create a Blob by wrapping the TypedArray in an Array
var blob = new Blob([uint8Array]);

// Create an object URL for image loading
var objectURL = URL.createObjectURL(blob);

// The subsequent image loading and Canvas drawing code remains unchanged
var canvas = document.getElementById(kb);
var context = canvas.getContext("2d");
var image = new Image();

image.onload = function() {
    var scale = g / j;
    if (scale > 4) scale = 4;
    if (scale < 1) scale = 1;
    
    context.globalAlpha = 1;
    
    for (var N = 0; N < scale; N++) {
        context.drawImage(image, N, N, g - scale + N, i - scale + N, 0, 0, j, k);
        context.globalAlpha *= 1 - 1 / scale;
    }
    
    // Clean up the object URL to free memory
    URL.revokeObjectURL(objectURL);
};

image.onerror = function() {
    console.error("Image /bmp.bmp could not be decoded!");
    // Clean up the object URL
    URL.revokeObjectURL(objectURL);
};

image.src = objectURL;

Performance Optimization and Best Practices

1. Memory Management: Object URLs created with URL.createObjectURL() consume memory and should be released by calling URL.revokeObjectURL() when no longer needed.

2. Error Handling: The Blob constructor may throw exceptions, especially when processing invalid data. Use try-catch blocks for appropriate error handling.

3. Type Checking: When dealing with uncertain data sources, validate input data types:

if (!(I instanceof ArrayBuffer)) {
    throw new TypeError("Input must be an ArrayBuffer");
}
if (ololo1 < 0 || ololo2 <= 0 || ololo1 + ololo2 > I.byteLength) {
    throw new RangeError("Offset or length out of range");
}

4. MIME Type Specification: When creating a Blob, you can specify the MIME type, which is crucial for the browser to correctly interpret the content:

var blob = new Blob([uint8Array], { type: "image/bmp" });

Compatibility Considerations

The Blob constructor is widely supported in modern browsers, including Chrome 20+, Firefox 13+, Safari 6+, Edge 12+, and Opera 15+. For projects requiring support for older browsers, consider using a polyfill or conditional checks:

if (typeof Blob !== "function") {
    // Fallback solution or error message
    console.error("Current browser does not support Blob API");
}

Conclusion

Converting ArrayBuffer to Blob is a fundamental operation in web development for handling binary data. The key is understanding that the Blob constructor expects a sequence containing BufferSource, not a direct TypedArray. By wrapping the TypedArray in an Array, you ensure the data is correctly interpreted as binary rather than strings. In practical applications, factors such as memory management, error handling, MIME type specification, and browser compatibility must also be considered to build robust and reliable binary data processing solutions.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.