I\'m trying to render a PNG image that is stored in a javascript Uint8Array
. The code that I originally tried was the following:
var imgByteStr
Full Working Example: (save as .html file and open)
1: Creates Uint8Array.
2: Fills it with debug pattern.
3: Pastes it to canvas element on page.
Output should like like below:
<!DOCTYPE HTML >
<html lang="en">
<head>
<meta charset="UTF-8">
<title> U8A_TO_CANVAS </title>
<meta name ="author"
content="John Mark Isaac Madison">
<!-- EMAIL: J4M4I5M7@HOTMAIL.com -->
</head>
<body>
<canvas id="CANVAS_ID"
width ="512"
height="512">
</canvas>
<script>
var com = 4 ; //:4 components( RGBA )
var wid = 512;
var hig = 512;
var tot_com = wid*hig*com;//:total#components
var u8a = new Uint8Array( tot_com );
DrawDebugPattern ( u8a , wid, hig );
Uint8ArrayToCanvas( u8a , wid, hig, "CANVAS_ID" );
function Uint8ArrayToCanvas(
u8a, //:uint8Array
wid, //:width__of_u8a_data_in_pixels
hig, //:height_of_u8a_data_in_pixels
nam, //:name_id_of_canvas_on_dom
){
//:Get Canvas:
var can = document.getElementById( nam );
if(!can){ throw "[FailedToGetCanvas]"; }
//:Get Canvas's 2D Context:
var ctx = can.getContext("2d");
if(!ctx){ throw "[FailedToGetContext]"; }
//:Use U8A to create image data object:
var UAC = new Uint8ClampedArray( u8a,wid,hig);
var DAT = new ImageData(UAC, wid, hig);
//:Paste Data Into Canvas:
var ORG_X = 0;
var ORG_Y = 0;
ctx.putImageData( DAT, ORG_X, ORG_Y );
}
function DrawDebugPattern(u8a,wid,hig){
var com = 4 ; //:RGBA==4components.
var tot_pix = wid*hig;//:total#pixels
//:Calculate point in center of canvas:
var cen_x = wid/2;
var cen_y = hig/2;
//:Define a circle's radius:
var rad_c = Math.min(wid,hig) / 2;
//:Make a pattern on array:
var d = 0; //:d_is_for_distance
var ci = 0; //:Component_Index
var pi = 0; //:Pixel_Index
var px = 0; //:Pixel_X_Coord
var py = 0; //:Pixel_Y_Coord
for( pi = 0; pi < tot_pix; pi++ ){
//:Calculate index of first component
//:of current pixel:
ci = pi * com;
//:Index_To_XY_Formula:
px = pi % wid ;
py = (pi-px)/ wid ;
//:Decide if pixel is inside circle:
var dx = (cen_x-px); //:delta_x
var dy = (cen_y-py); //:delta_y
d=Math.sqrt( (dx*dx)+(dy*dy) );
if( d < rad_c ){
//:INSIDE_CIRCLE:
u8a[ ci + 0 ] = 0 ; //:Red
u8a[ ci + 1 ] = 255; //:Green
u8a[ ci + 2 ] = 0 ; //:Blue
u8a[ ci + 3 ] = 255; //:Alpha
}else{
//:OUTSIDE_CIRCLE:
u8a[ ci + 0 ] = 0 ; //:Red
u8a[ ci + 1 ] = 0 ; //:Green
u8a[ ci + 2 ] = 64 ; //:Blue
u8a[ ci + 3 ] = 255; //:Alpha
}
}
}
</script>
</body>
<!-- In IE: Script cannot be outside of body. -->
</html>
If you already have a UInt8Array, you should consider using Blob
and createObjectURL
; createObjectURL allocates a special URL that allows the browser to access an internally created blob of binary data as though it were a file being loaded externally.
Where it is supported, createObjectURL
is an excellent alternative to huge data URIs. You may still need to fall back to use of data URIs in Opera, IE<10, and all but the most recent versions of mobile browsers.
var myArray; //= your data in a UInt8Array
var blob = new Blob([myArray], {'type': 'image/png'});
var url = URL.createObjectURL(blob); //possibly `webkitURL` or another vendor prefix for old browsers.
If you have the PNG data in memory (which I think is what you're describing) then you can create an image from it. In HTML it would look like:
<img src="data:image/png;base64,KSjs9JdldhAlisflAkshf==" />
In JavaScript you can do the same:
var image = document.createElement('img');
image.src = 'data:image/png;base64,' + base64Data;
Note that you can change the MIME type if you don't have PNG data.
You could then draw the image
onto your canvas using context.drawImage(image, 0, 0)
or similar.
So the remaining part of the puzzle is to encode the contents of your Uint8Array
into Base 64 data.
var array = new Uint8Array(),
base64Data = btoa(String.fromCharCode.apply(null, array));
The function btoa
isn't standard, so some browsers might not support it. However it seems that most do. Otherwise you might find some code I use helpful.
I haven't tested any of this myself!