使用 DataView 和 TypedArrays 交换字节顺序
Swapping byte order with DataView and TypedArrays
大家好,我正在学习 DataView 和 TypedArrays。
我有一个 LONG 数组和 USIGGNED_LONG 数组,我将把 LONG 数组粘贴到下面。
我一直在尝试将底部的 ARGB 数组替换为 RGBA。我做的第一步是将其设为 Uint32Array
,但之后我在交换字节时遇到了麻烦。谢谢
var buffer = new ArrayBuffer(argb_16x16_LONG.length * 4);
var view = new DataView(buffer);
var argb_16x16_LONG = [
'16777215',
'50331648',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'50331648',
'16777215',
'117440512',
'-179727685',
'-13794122',
'-7501709',
'-2579612',
'-12091753',
'-11689787',
'-8663845',
'-8729638',
'-12612424',
'-12360329',
'-4941740',
'-670645',
'-342721',
'-106524059',
'117440512',
'520093696',
'-1924502',
'-3243974',
'-1669338',
'-9017258',
'-15895118',
'-13397058',
'-10042412',
'-10042412',
'-13991247',
'-16164456',
'-16298359',
'-10130877',
'-600557',
'-137156',
'520093696',
'587202560',
'-2000091',
'-2199019',
'-2199024',
'-8563138',
'-15965032',
'-11755851',
'-10108719',
'-10042669',
'-13596748',
'-16164712',
'-15902826',
'-16233077',
'-12693681',
'-669681',
'587202560',
'587202560',
'-2066396',
'-2133221',
'-2660335',
'-3126519',
'-2206455',
'-5019855',
'-10505018',
'-11227448',
'-13004873',
'-13005900',
'-10636341',
'-11559489',
'-16434316',
'-4224992',
'587202560',
'654311424',
'-2066654',
'-2133221',
'-2133221',
'-1666476',
'-1001601',
'-7692655',
'-10307379',
'-11557437',
'-10767926',
'-10636854',
'-12744270',
'-11428673',
'-14722936',
'-3237322',
'654311424',
'654311424',
'-2066655',
'-2133221',
'-2066657',
'-2324167',
'-10773841',
'-10572087',
'-10506038',
'-10506038',
'-10901050',
'-15904626',
'-15839603',
'-14326887',
'-11563857',
'-1390041',
'654311424',
'687865856',
'-2132705',
'-2923495',
'-3510485',
'-4092338',
'-11497296',
'-10837309',
'-10771004',
'-10771004',
'-10837053',
'-13536862',
'-16434563',
'-15975303',
'-14068866',
'-802546',
'687865856',
'704643072',
'-5755123',
'-6086910',
'-8760247',
'-11696978',
'-11563854',
'-11234117',
'-11168068',
'-11168068',
'-11233860',
'-12485462',
'-16502669',
'-16570265',
'-7640013',
'-548596',
'704643072',
'721420288',
'-5100540',
'-4246015',
'-3513571',
'-10724253',
'-12162676',
'-10721420',
'-7048367',
'-8553877',
'-11961433',
'-12751710',
'-16044432',
'-16638627',
'-1590456',
'-481270',
'721420288',
'754974720',
'-3127291',
'-2274304',
'-2203377',
'-2133221',
'-2133221',
'-2133221',
'-2264291',
'-2256322',
'-11182995',
'-16639135',
'-16770980',
'-16312757',
'-666027',
'-413935',
'754974720',
'771751936',
'-2068969',
'-2007285',
'-2138099',
'-5887736',
'-5492214',
'-4896748',
'-6795731',
'-12760969',
'-14600580',
'-16772007',
'-13555655',
'-5738717',
'-268799',
'-479193',
'771751936',
'805306368',
'-2132966',
'-2199019',
'-2133992',
'-3249890',
'-10996944',
'-16312751',
'-13880445',
'-15720598',
'-13880957',
'-12571067',
'-2855395',
'-1337332',
'-935936',
'-274084',
'805306368',
'822083584',
'-2066404',
'-2199024',
'-2133226',
'-2199021',
'-2133223',
'-5219036',
'-9749959',
'-9225160',
'-7386577',
'-2658787',
'-2132966',
'-1669883',
'-871912',
'-134302',
'822083584',
'520093696',
'-106147016',
'-2794469',
'-2198244',
'-2066144',
'-2066148',
'-1933785',
'-1867216',
'-1867215',
'-1933779',
'-2000089',
'-2135789',
'-1602038',
'-132835',
'-104553172',
'520093696',
'50331648',
'822083584',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'822083584',
'50331648'
];
您可以使用 DataView 的读取方法将 16 位或 32 位值读取为小端或大端(默认),如下所示:
var uint32lsb = view.getUint32(0, true); // little-endian, from byte-position 0 in buffer
var uint32msb = view.getUint32(0, false); // big-endian, last argument is optional
当然 getInt32()
/getUint16()
/getInt16()
也一样(当然是单字节,没有字节顺序,即 getInt8()
等)。
如果缓冲区是 big-endian 并且您手动将其读取为 big-endian,您现在可以像这样移动和屏蔽每个字节的值:
var a = (uint32be & 0xff000000)>>>24;
var r = (uint32be & 0xff0000)>>>16;
var g = (uint32be & 0xff00)>>>8;
var b = uint32be & 0xff;
如果你读的是小端,就把顺序倒过来:
var a = uint32le & 0xff;
var r = (uint32le & 0xff00)>>>8;
var g = (uint32le & 0xff0000)>>>16;
var b = (uint32le & 0xff000000)>>>24;
只要知道缓冲区的原始顺序,您也可以读取单个字节。例如,如果缓冲区是 big-endian,您可以像这样读取前四个字节:
var pos = 0;
var a = view.getUint8(pos++);
var r = view.getUint8(pos++);
var g = view.getUint8(pos++);
var b = view.getUint8(pos++);
在你的例子中,缓冲区是空的,所以你只会得到 0。要创建具有 32 个 uint 值的类型化数组缓冲区,然后获得 DataView
,您可以执行以下操作:
var buffer32 = new Uint32Array(argb_16x16_LONG);
var view = new DataView(buffer32.buffer); // or the original argb_16x16_LONG directly
(它们指向相同的底层 ArrayBuffer,因此没有为缓冲区分配新内存。)
希望对您有所帮助。
大家好,我正在学习 DataView 和 TypedArrays。
我有一个 LONG 数组和 USIGGNED_LONG 数组,我将把 LONG 数组粘贴到下面。
我一直在尝试将底部的 ARGB 数组替换为 RGBA。我做的第一步是将其设为 Uint32Array
,但之后我在交换字节时遇到了麻烦。谢谢
var buffer = new ArrayBuffer(argb_16x16_LONG.length * 4);
var view = new DataView(buffer);
var argb_16x16_LONG = [
'16777215',
'50331648',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'117440512',
'50331648',
'16777215',
'117440512',
'-179727685',
'-13794122',
'-7501709',
'-2579612',
'-12091753',
'-11689787',
'-8663845',
'-8729638',
'-12612424',
'-12360329',
'-4941740',
'-670645',
'-342721',
'-106524059',
'117440512',
'520093696',
'-1924502',
'-3243974',
'-1669338',
'-9017258',
'-15895118',
'-13397058',
'-10042412',
'-10042412',
'-13991247',
'-16164456',
'-16298359',
'-10130877',
'-600557',
'-137156',
'520093696',
'587202560',
'-2000091',
'-2199019',
'-2199024',
'-8563138',
'-15965032',
'-11755851',
'-10108719',
'-10042669',
'-13596748',
'-16164712',
'-15902826',
'-16233077',
'-12693681',
'-669681',
'587202560',
'587202560',
'-2066396',
'-2133221',
'-2660335',
'-3126519',
'-2206455',
'-5019855',
'-10505018',
'-11227448',
'-13004873',
'-13005900',
'-10636341',
'-11559489',
'-16434316',
'-4224992',
'587202560',
'654311424',
'-2066654',
'-2133221',
'-2133221',
'-1666476',
'-1001601',
'-7692655',
'-10307379',
'-11557437',
'-10767926',
'-10636854',
'-12744270',
'-11428673',
'-14722936',
'-3237322',
'654311424',
'654311424',
'-2066655',
'-2133221',
'-2066657',
'-2324167',
'-10773841',
'-10572087',
'-10506038',
'-10506038',
'-10901050',
'-15904626',
'-15839603',
'-14326887',
'-11563857',
'-1390041',
'654311424',
'687865856',
'-2132705',
'-2923495',
'-3510485',
'-4092338',
'-11497296',
'-10837309',
'-10771004',
'-10771004',
'-10837053',
'-13536862',
'-16434563',
'-15975303',
'-14068866',
'-802546',
'687865856',
'704643072',
'-5755123',
'-6086910',
'-8760247',
'-11696978',
'-11563854',
'-11234117',
'-11168068',
'-11168068',
'-11233860',
'-12485462',
'-16502669',
'-16570265',
'-7640013',
'-548596',
'704643072',
'721420288',
'-5100540',
'-4246015',
'-3513571',
'-10724253',
'-12162676',
'-10721420',
'-7048367',
'-8553877',
'-11961433',
'-12751710',
'-16044432',
'-16638627',
'-1590456',
'-481270',
'721420288',
'754974720',
'-3127291',
'-2274304',
'-2203377',
'-2133221',
'-2133221',
'-2133221',
'-2264291',
'-2256322',
'-11182995',
'-16639135',
'-16770980',
'-16312757',
'-666027',
'-413935',
'754974720',
'771751936',
'-2068969',
'-2007285',
'-2138099',
'-5887736',
'-5492214',
'-4896748',
'-6795731',
'-12760969',
'-14600580',
'-16772007',
'-13555655',
'-5738717',
'-268799',
'-479193',
'771751936',
'805306368',
'-2132966',
'-2199019',
'-2133992',
'-3249890',
'-10996944',
'-16312751',
'-13880445',
'-15720598',
'-13880957',
'-12571067',
'-2855395',
'-1337332',
'-935936',
'-274084',
'805306368',
'822083584',
'-2066404',
'-2199024',
'-2133226',
'-2199021',
'-2133223',
'-5219036',
'-9749959',
'-9225160',
'-7386577',
'-2658787',
'-2132966',
'-1669883',
'-871912',
'-134302',
'822083584',
'520093696',
'-106147016',
'-2794469',
'-2198244',
'-2066144',
'-2066148',
'-1933785',
'-1867216',
'-1867215',
'-1933779',
'-2000089',
'-2135789',
'-1602038',
'-132835',
'-104553172',
'520093696',
'50331648',
'822083584',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'1493172224',
'822083584',
'50331648'
];
您可以使用 DataView 的读取方法将 16 位或 32 位值读取为小端或大端(默认),如下所示:
var uint32lsb = view.getUint32(0, true); // little-endian, from byte-position 0 in buffer
var uint32msb = view.getUint32(0, false); // big-endian, last argument is optional
当然 getInt32()
/getUint16()
/getInt16()
也一样(当然是单字节,没有字节顺序,即 getInt8()
等)。
如果缓冲区是 big-endian 并且您手动将其读取为 big-endian,您现在可以像这样移动和屏蔽每个字节的值:
var a = (uint32be & 0xff000000)>>>24;
var r = (uint32be & 0xff0000)>>>16;
var g = (uint32be & 0xff00)>>>8;
var b = uint32be & 0xff;
如果你读的是小端,就把顺序倒过来:
var a = uint32le & 0xff;
var r = (uint32le & 0xff00)>>>8;
var g = (uint32le & 0xff0000)>>>16;
var b = (uint32le & 0xff000000)>>>24;
只要知道缓冲区的原始顺序,您也可以读取单个字节。例如,如果缓冲区是 big-endian,您可以像这样读取前四个字节:
var pos = 0;
var a = view.getUint8(pos++);
var r = view.getUint8(pos++);
var g = view.getUint8(pos++);
var b = view.getUint8(pos++);
在你的例子中,缓冲区是空的,所以你只会得到 0。要创建具有 32 个 uint 值的类型化数组缓冲区,然后获得 DataView
,您可以执行以下操作:
var buffer32 = new Uint32Array(argb_16x16_LONG);
var view = new DataView(buffer32.buffer); // or the original argb_16x16_LONG directly
(它们指向相同的底层 ArrayBuffer,因此没有为缓冲区分配新内存。)
希望对您有所帮助。