display .raw file image in browser

4k views Asked by At

I have a image file in .raw format which is directly read from fingerprint scanner device. We have to display that in a browser using html and javascript. How can we convert the .raw image and display in the browser?

Following is the manual steps I used to convert using online tools

I am able to convert that hex content as .raw file using online converter http://tomeko.net/online_tools/hex_to_file.php?lang=en

and converted raw file can be converted again as jpeg file by https://www.iloveimg.com/convert-to-jpg/raw-to-jpg url

Sample file will look like this https://i.stack.imgur.com/bnycl.jpg

I tried the following code to display hex content in the browser but didnt work.

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

var img = new Image();
img.src = "data:image/jpeg;base64,"+hexToBase64(getBinary());
document.body.appendChild(img);

complete jsfiddle is http://jsfiddle.net/varghees/79NnG/1334/

1

There are 1 answers

1
Kaiido On BEST ANSWER

First, what you have provided in your fiddle is probably not a .raw file.

While there are tons of different file formats using this extension, I don't quite bite the fact there is no metadata at all, since this is required to at least know the image's size.

So I'm sorry for future readers, but this answer only shows how to convert raw 8bit values into an actual image...

So now, without image size, but if the image is squared, we can actually do it from the byteLength only, (both width and height will be the square-root of the byteLength).

The general steps are

  • (convert your hex string to an actual Uint8Array)
  • set all 4th values of an Uint8ClampedArray 4 times bigger than the first Uint8Array (this will set the Alpha channel of our soon to be RGBA image)
  • pass this Uint8ClampedArray in the ImageData() constructor.
  • put this ImageData on a canvas
  • Tadaa!

So using a square full of random values (and thus avoid the hex to buffer conversion):

const fake = new Uint8Array( 256*256 );
crypto.getRandomValues(fake); // get random values

processSquareBitmap(fake.buffer);

function processSquareBitmap(buffer) {
 const view = new Uint8Array(buffer);
  const out = new Uint8ClampedArray(buffer.byteLength * 4);
  const size = Math.sqrt(view.length);
  if(size % 1) {
   console.error('not a square');
    return;
  }
  // set alpha channel
  view.forEach((a,i)=>out[(i*4)+3] = a);
  const image = new ImageData(out, size, size)
  const canvas = document.createElement('canvas');
  canvas.width = canvas.height = size;
  canvas.getContext('2d').putImageData(image, 0,0);
  // if you want to save a png version
//  canvas.toBlob(b=> saveAs(b, 'bitmap.png'));
  document.body.appendChild(canvas);
}

But for not squared images, you must have the actual width and height.
I was able to deduce the ones of OP's hex data, and thus could make this fiddle which will display their image.