Javascript 画布到32位压缩ARGB

Javascript 画布到32位压缩ARGB,javascript,html,canvas,xlib,Javascript,Html,Canvas,Xlib,我有一个html5画布元素,我正在尝试获取一个ARGB数据数组(32位压缩数据,用于x11/xorg/xlib)。但是我不知道怎么做 例如,这是处理数据时应显示的内容(此处包含16x16图像和32x32图像): 这是我的尝试: var can=document.getElementById('mycan'); can.width='16'; can.height='16'; var ctx=can.getContext('2d'); ctx.fillStyle=“rgb(255,0,0)”;

我有一个html5画布元素,我正在尝试获取一个ARGB数据数组(32位压缩数据,用于x11/xorg/xlib)。但是我不知道怎么做

例如,这是处理数据时应显示的内容(此处包含
16x16
图像和
32x32
图像):

这是我的尝试:

var can=document.getElementById('mycan');
can.width='16';
can.height='16';
var ctx=can.getContext('2d');
ctx.fillStyle=“rgb(255,0,0)”;
ctx.fillRect(0,0,16,16);
var ARGBpixmap=[16,16];
var image_data=ctx.getImageData(0,0,can.width,can.height);
对于(var x=0;x
我倾向于使用
TypedArray
来简化从8位整数到32位整数的转换(并且更优化):

//将像素作为字节(uint8)数组获取
var imageData=ctx.getImageData(0,0,can.width,can.height);
var pixels8BitsRGBA=imageData.data;
//正在将字节从RGBA还原为ARGB
var pixels8BitsARGB=新的Uint8Array(pixels8BitsRGBA.length+8);//+两个前导32字节整数的8字节
对于(变量i=0;i

编辑:不幸的是,此代码不可靠,因为它取决于您的体系结构(类型化数组取决于endianness)

我尝试了另一种使用位运算符的方法,但在更改第32位时,我得到了错误的结果

这太疯狂了,但我发现让它工作的唯一方法不是干净或优化:

// Getting pixels as a byte (uint8) array
var imageData = ctx.getImageData(0, 0, can.width, can.height);
var pixels8BitsRGBA = imageData.data;

// Reverting bytes from RGBA to ARGB
var pixels8BitsARGB = new Uint8Array(pixels8BitsRGBA.length + 8); // +8 bytes for the two leading 32 bytes integers
for(var i = 0 ; i < pixels8BitsRGBA.length ; i += 4) {
    pixels8BitsARGB[i+8 ] = pixels8BitsRGBA[i+3];
    pixels8BitsARGB[i+9 ] = pixels8BitsRGBA[i  ];
    pixels8BitsARGB[i+10] = pixels8BitsRGBA[i+1];
    pixels8BitsARGB[i+11] = pixels8BitsRGBA[i+2];
}

// Converting array buffer to a uint32 one, and adding leading width and height
var pixelsAs32Bits = new Uint32Array(pixels8BitsARGB.buffer);
pixelsAs32Bits[0] = can.width;
pixelsAs32Bits[1] = can.height;

console.log(pixelsAs32Bits);
var imageData = ctx.getImageData(0, 0, can.width, can.height);
var pixelsRGBA = imageData.data;
var pixelCount = pixelsRGBA.length / 4;

var pixelsARGBPacked = new Array(2 + pixelCount);
pixelsARGBPacked[0] = can.width;
pixelsARGBPacked[1] = can.height;
for(var i = 0 ; i < pixelCount ; i++) {
    pixelsARGBPacked[i+2] = parseInt(
          pixelsRGBA[i * 4 + 3].toString(16)
        + pixelsRGBA[i * 4    ].toString(16)
        + pixelsRGBA[i * 4 + 1].toString(16)
        + pixelsRGBA[i * 4 + 2].toString(16)
    , 16);
}

console.log(pixelsARGBPacked);
var imageData=ctx.getImageData(0,0,can.width,can.height);
var pixelsRGBA=imageData.data;
var pixelCount=pixelsRGBA.length/4;
var pixelsARGBPacked=新阵列(2+像素计数);
pixelsARGBPacked[0]=can.width;
pixelsARGBPacked[1]=罐高;
对于(var i=0;i
我发现了一个巧妙的技巧来修复第32位的奇怪行为。 如果要将
argb
值转换为常规argb int,则必须使用
0
执行无符号右移
>
。然后强制该值变为无符号整数。在nodejs中进行测试

var a = 0xFF, r = 0xFF, g = 0x00, b = 0xFF;
result1 = (((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff)) >>> 0;
result2 = (((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff));
var a=0xFF,r=0xFF,g=0x00,b=0xFF;
结果1=((a&0xff)0;

结果2=((a&0xff)哇,非常感谢你这么快的回复和这么好的回答。我明天会测试它,让你知道它是如何工作的!:)嘿,伙计,我刚刚测试过,图像看起来很蓝:(这是一张显示其外观的图像。左侧为全蓝色。右侧为原始图像:一个实心的红色填充图像显示为灰色。数组为
[16,16,65535,65535,…,65535]
基本上都是
65535
,我真的很感谢您的帮助!@Noitidart我编辑了我的答案。我对代码不满意,但它可以工作:s@SebastienC.+1个不错的答案。一种干净处理“endian ness”的方法是使用javascript的
DataView
var imageData = ctx.getImageData(0, 0, can.width, can.height);
var pixelsRGBA = imageData.data;
var pixelCount = pixelsRGBA.length / 4;

var pixelsARGBPacked = new Array(2 + pixelCount);
pixelsARGBPacked[0] = can.width;
pixelsARGBPacked[1] = can.height;
for(var i = 0 ; i < pixelCount ; i++) {
    pixelsARGBPacked[i+2] = parseInt(
          pixelsRGBA[i * 4 + 3].toString(16)
        + pixelsRGBA[i * 4    ].toString(16)
        + pixelsRGBA[i * 4 + 1].toString(16)
        + pixelsRGBA[i * 4 + 2].toString(16)
    , 16);
}

console.log(pixelsARGBPacked);
var a = 0xFF, r = 0xFF, g = 0x00, b = 0xFF;
result1 = (((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff)) >>> 0;
result2 = (((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff));