在 JavaScript 中将原始图像的十六进制字符串转换为位图图像 [英] Converting a hex string of a raw image to a bitmap image in JavaScript

查看:38
本文介绍了在 JavaScript 中将原始图像的十六进制字符串转换为位图图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简介:

我正在从智能卡读取指纹图像数据,正如您所知,这些数据在智能卡中保存为原始图像.我正在开发一个客户端程序,该程序仅使用 java 脚本从读卡器的扫描仪读取图像并将其显示在客户端页面中.

现在我的问题:

如何将原始数据的十六进制字符串转换为使用位图图像的适当标头完成的十六进制字符串?请注意,我的图像有 widthheight.

尝试过的方法:

我已经通过 从原始数据中获取缓冲图像.另外,我可以通过 Hex2Base64 然后我可以通过 base64AsImage 在图像标签中显示 base64 字符串.然而,当且仅当十六进制包含标题,而我们的数据是原始数据时,这些函数才能正常工作.

我的代码(仅适用于包含标题的十六进制字符串):

<head lang="en"><meta charset="UTF-8"><title></title><脚本>如果(!window.atob){var tableStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var table = tableStr.split("");window.atob = 函数(base64){if (/(=[^=]+|={3,})$/.test(base64)) throw new Error("String contains an invalid character");base64 = base64.replace(/=/g, "");var n = base64.length &3;if (n === 1) throw new Error("字符串包含无效字符");for (var i = 0, j = 0, len = base64.length/4, bin = []; i < len; ++i) {var a = tableStr.indexOf(base64[j++] || "A"), b = tableStr.indexOf(base64[j++] || "A");var c = tableStr.indexOf(base64[j++] || "A"), d = tableStr.indexOf(base64[j++] || "A");if ((a | b | c | d) <0) throw new Error("String contains an invalid character");bin[bin.length] = ((a <<2) | (b >> 4)) &255;bin[bin.length] = ((b <<4) | (c >> 2)) &255;bin[bin.length] = ((c <<6) | d) &255;};返回 String.fromCharCode.apply(null, bin).substr(0, bin.length + n - 4);};window.btoa = 函数(bin){for (var i = 0, j = 0, len = bin.length/3, base64 = []; i < len; ++i) {var a = bin.charCodeAt(j++), b = bin.charCodeAt(j++), c = bin.charCodeAt(j++);if ((a | b | c) > 255) throw new Error("String contains an invalid character");base64[base64.length] = table[a >>2] + 表[((a << 4) & 63) |(b > > 4)] +(isNaN(b) ? "=": table[((b <<2) & 63) | (c >> 6)]) +(isNaN(b + c) ? "=" : table[c & 63]);}返回 base64.join("");};}函数 hexToBase64(str) {返回 btoa(String.fromCharCode.apply(null,str.replace(/
|
/g, "").replace(/([da-fA-F]{2}) ?/g, "0x$1 ").replace(/+$/,).分裂(" ")));}函数 base64ToHex(str) {for (var i = 0, bin = atob(str.replace(/[ 
]+$/, "")), hex = []; i <身体><div><p>输入原始十六进制:<br><textarea rows="4" cols="50" id="myText">在此处输入原始十六进制字符串...</textarea><br><button id="myButton" onclick="doConvert()">点击我</button><br><img id="myImage" alt="img1"/></p>

a 部分代码解决了java中的问题:

私有静态BufferedImage byte2Buffered(byte[] rawData, int width, int height){BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_BYTE_GRAY);byte[] array = ((DataBufferByte)image.getRaster().getDataBuffer()).getData();System.arraycopy(rawData, 0, array, 0, rawData.length);返回图像;}

请注意,由于 JavaScript 中没有 BufferedImage 类型,我们无法在 JavaScript 中等效这种方法.

解决方案

在您的 window.atob 方法中,您已经从 8 位整数数组构建了一个字符串(这就是 bin[length] 正在创建.)只需返回该数组而不是字符串.

然后,如果您必须支持较旧的浏览器,则需要将每个像素单独写入画布.但是,如果您可以针对现代浏览器,只需构建一个 Uint8ClampedArray,将其放入 ImageData 对象,然后将 putImageData() 放入画布.

下面是一些工作示例代码.我正在用随机字节(data)填充一个虚拟数组,但您将使用从 atob 返回的字节数组.

var canvas = document.querySelector('canvas'),ctx = canvas.getContext('2d'),宽度 = 画布宽度,高度 = 画布高度,像素长度 = 宽度 * 高度,数据,图像数据;//你可以使用任何类型的数组,包括一个//Uint8ClampedArray,因为它将是//无论如何都塞进了一个钳位数组.我正在使用//Uint8Array 只是一个例子.数据 = 新的 Uint8Array(pixelLength);//创建一个随机数据数组data = data.map(function (btye) { return Math.floor(Math.random() * 256); });//源数据是8位灰度,但需要//成为 Uint8ClampedArray 中的 32 位 RGBA.这//结构简单.对于灰色的每个字节//缩放数组,写出该字节的三个副本//然后 `256` 为 100% 不透明.数据 = data.reduce(函数(进位,当前,索引){var baseIndex = 索引 * 4;进位[baseIndex] = 当前;进位[baseIndex + 1] = 当前;进位[baseIndex + 2] = 当前;进位[baseIndex + 3] = 256;回程;}, new Uint8ClampedArray(pixelLength * 4));//现在可以使用 Uint8ClampedArray 来构建图像imageData = new ImageData(data, width, height);ctx.putImageData(imageData, 0, 0);

Introduction:

I am reading image data of fingerprints from smart card and as you know this data save as raw image in smart card. I am developing a client side program which only use java script to read image from scanner of a card reader and show that in the client page.

Now my question:

How can I convert hex string of my raw data to a hex string which accomplished with appropriate header of bitmap image? Note that I have width and height of my image.

Tried methods:

I have been developed this program in java by get buffered image from raw data. Also, I could convert a hex string of a bit map image to base64 by Hex2Base64 and then I could show base64 string in an image tag by base64AsImage. However these functions work well if and only if the hex contains header, while our data is raw.

My code (that only works for Hex String which contains header):

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>

    <script>
        if (!window.atob) {
            var tableStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
            var table = tableStr.split("");

            window.atob = function (base64) {
                if (/(=[^=]+|={3,})$/.test(base64)) throw new Error("String contains an invalid character");
                base64 = base64.replace(/=/g, "");
                var n = base64.length & 3;
                if (n === 1) throw new Error("String contains an invalid character");
                for (var i = 0, j = 0, len = base64.length / 4, bin = []; i < len; ++i) {
                    var a = tableStr.indexOf(base64[j++] || "A"), b = tableStr.indexOf(base64[j++] || "A");
                    var c = tableStr.indexOf(base64[j++] || "A"), d = tableStr.indexOf(base64[j++] || "A");
                    if ((a | b | c | d) < 0) throw new Error("String contains an invalid character");
                    bin[bin.length] = ((a << 2) | (b >> 4)) & 255;
                    bin[bin.length] = ((b << 4) | (c >> 2)) & 255;
                    bin[bin.length] = ((c << 6) | d) & 255;
                };
                return String.fromCharCode.apply(null, bin).substr(0, bin.length + n - 4);
            };

            window.btoa = function (bin) {
                for (var i = 0, j = 0, len = bin.length / 3, base64 = []; i < len; ++i) {
                    var a = bin.charCodeAt(j++), b = bin.charCodeAt(j++), c = bin.charCodeAt(j++);
                    if ((a | b | c) > 255) throw new Error("String contains an invalid character");
                    base64[base64.length] = table[a >> 2] + table[((a << 4) & 63) | (b >> 4)] +
                    (isNaN(b) ? "=" : table[((b << 2) & 63) | (c >> 6)]) +
                    (isNaN(b + c) ? "=" : table[c & 63]);
                }
                return base64.join("");
            };

        }

        function hexToBase64(str) {
            return btoa(String.fromCharCode.apply(null,
                            str.replace(/
|
/g, "").replace(/([da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" "))
            );
        }

        function base64ToHex(str) {
            for (var i = 0, bin = atob(str.replace(/[ 
]+$/, "")), hex = []; i < bin.length; ++i) {
                var tmp = bin.charCodeAt(i).toString(16);
                if (tmp.length === 1) tmp = "0" + tmp;
                hex[hex.length] = tmp;
            }
            return hex.join(" ");
        }
        function doConvert() {
            var myHex =  document.getElementById('myText').value;
            var myBase64 = hexToBase64(myHex);
            document.getElementById('myImage').src = "data:image/bmp;base64," +  myBase64;
        }
    </script>



</head>
<body>
<div>
    <p>
        Enter Raw Hex:
        <br>
        <textarea rows="4" cols="50" id="myText">Enter Raw Hex String here ...</textarea>
        <br>
        <button id="myButton" onclick="doConvert()"> Click me </button>
        <br>
        <img id="myImage" alt="img1"/>
    </p>
</div>
</body>
</html>

a part of code which solve the problem in java:

private static BufferedImage byte2Buffered(byte[] rawData, int width, int height){
    BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_BYTE_GRAY);
    byte[] array = ((DataBufferByte)image.getRaster().getDataBuffer()).getData();
    System.arraycopy(rawData, 0, array, 0, rawData.length);
    return image;
}

Notice that, as there is not BufferedImage type in JavaScript, we could not equivalent this approach in JavaScript.

解决方案

In your window.atob method, you are building a string from an array of 8-bit integers already (that's what bin[length] is creating.) Just return that array instead of the string.

Then, if you have to support older browsers, you will need to write each pixel to the canvas individually. But if you can target modern browsers, just build a Uint8ClampedArray, put that into an ImageData object, and putImageData() into the canvas.

Below is some working sample code. I'm populating a dummy array with random bytes (data), but you would use the byte array returned from atob.

var canvas = document.querySelector('canvas'),
    ctx = canvas.getContext('2d'),
  width = canvas.width,
  height = canvas.height,
  pixelLength = width * height,
  data,
  imageData;

// You can use any kind of array, including a
// Uint8ClampedArray, since it is just going to be
// crammed into a clamped array anyway. I'm using a
// Uint8Array just as an example.
data = new Uint8Array(pixelLength);

// Create an array of random data
data = data.map(function (btye) { return Math.floor(Math.random() * 256); });

// The source data is 8-bit grayscale, but it needs 
// to be 32-bit RGBA in a Uint8ClampedArray. The
// structure is simple. For every byte of the gray-
// scale array, write out three copies of that byte 
// and then `256` as 100% opaque.
data = data.reduce(function (carry, current, index) {
    var baseIndex = index * 4;

  carry[baseIndex] = current;
    carry[baseIndex + 1] = current;
    carry[baseIndex + 2] = current;
    carry[baseIndex + 3] = 256;

return carry;
}, new Uint8ClampedArray(pixelLength * 4));

// The Uint8ClampedArray can now be used to build the image
imageData = new ImageData(data, width, height);
ctx.putImageData(imageData, 0, 0);

这篇关于在 JavaScript 中将原始图像的十六进制字符串转换为位图图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆