zas*_*shu 21 javascript html5-canvas
我正在尝试渲染存储在javascript中的PNG图像Uint8Array.我最初尝试的代码如下:
var imgByteStr = String.fromCharCode.apply(null, this.imgBytes);
var pageImg = new Image();
pageImg.onload = function(e) {
// Draw onto the canvas
canvasContext.drawImage(pageImg, 0, 0);
};
// Attempt to generate the Data URI from the binary
// 3rd-party library adds toBase64() as a string function
pageImg.src="data:image/png;base64,"+encodeURIComponent(imgByteStr.toBase64());
Run Code Online (Sandbox Code Playgroud)
但是,我发现由于某种原因,onload函数从未运行(我在chrome中设置了断点并且它根本就没有命中).我发现如果我将src设置为URL而不是数据URI,它可以正常工作.但是,由于一些限制,我不能直接引用图像的URL,即它必须从中加载UInt8Array.
此外,为了使事情略微复杂化,这些图像的大小可能是兆字节.根据我的阅读,尝试将数据URI用于非常大的图像存在兼容性问题.因此,我对使用它们非常犹豫.
因此,问题是如何在不使用数据URI或直接引用图像URL的情况下将此字节数组作为PNG渲染到画布上下文中?
我也尝试使用类似下面的东西直接使用该putImageData函数操作图像数据.请记住,我并不是100%了解此功能的工作原理
var imgdata = canvasContext.createImageData(this.baseHeight, this.baseWidth);
var imgdatalen = imgdata.data.length;
for(var i=0; i<imgdatalen; i++) {
imgdata.data[i] = _this.imgBytes[i];
}
canvasContext.putImageData(imgdata, 0, 0);
Run Code Online (Sandbox Code Playgroud)
它是从一个我已经关闭的标签的博客中解除的,所以对没有给予适当信用的灵感表示道歉.
此外,在慢慢锤击这件事的同时,我在Chrome中遇到了错误SECURITY_ERR: DOM Exception 18.事实证明,只要使用drawImage将图像加载到画布中,就无法在没有其他解决方法的情况下检索图像.一个Chromium博客博文的主题是特别有用
Dre*_*kes 22
如果您在内存中有PNG数据(我认为这就是您所描述的),那么您可以从中创建图像.在HTML中它看起来像:
<img src="data:image/png;base64,KSjs9JdldhAlisflAkshf==" />
Run Code Online (Sandbox Code Playgroud)
在JavaScript中,您可以这样做:
var image = document.createElement('img');
image.src = 'data:image/png;base64,' + base64Data;
Run Code Online (Sandbox Code Playgroud)
请注意,如果您没有PNG数据,则可以更改MIME类型.
然后,您可以image使用context.drawImage(image, 0, 0)或类似地在画布上绘制.
因此,难题的其余部分是将您的内容编码Uint8Array为Base 64数据.
var array = new Uint8Array(),
base64Data = btoa(String.fromCharCode.apply(null, array));
Run Code Online (Sandbox Code Playgroud)
该功能btoa不是标准功能,因此某些浏览器可能不支持它.然而,似乎大多数人都这么做.否则你可能会发现我使用的一些代码很有用.
我自己没有测试过这些!
ell*_*ben 20
如果你已经有了一个UInt8Array,你应该考虑使用Blob和createObjectURL; createObjectURL分配一个特殊的URL,允许浏览器访问内部创建的二进制数据blob,就好像它是一个外部加载的文件.
支持它的地方,createObjectURL是巨大数据URI的绝佳替代品.您可能仍需要回退使用Opera,IE <10以及除最新版本的移动浏览器之外的所有数据URI.
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.
Run Code Online (Sandbox Code Playgroud)
完整工作示例:(另存为 .html 文件并打开)
1:创建 Uint8Array。
2:用调试模式填充它。
3:将其粘贴到页面上的画布元素。
输出应如下所示:
<!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>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17044 次 |
| 最近记录: |