gpt4 book ai didi

ARGB 到 RGBA 数组转换的 JavaScript 优化版本

转载 作者:行者123 更新时间:2023-12-02 21:30:11 25 4
gpt4 key购买 nike

我想将包含 ARGB 图像的字节 Uint8Array 转换为其 RGBA 表示形式,但是我希望通过比我在这里建议的更优化的方式来实现这一点,例如使用字节移位.

我现在所做的只是交换字节顺序(例如,但长度可以是 4 的任意倍数):

let input = [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 ];
let expected = [0x22, 0x33, 0x44, 0x11, 0x88, 0x55, 0x66, 0x77 ];

所以简单的情况是:

function argbToRgba(src) {
let dest = new Uint8Array(src.length)

for (let i = 0; i < src.length; i += 4) {
let a = src[i]
let r = src[i + 1]
let g = src[i + 2]
let b = src[i + 3]

dest[i] = r;
dest[i + 1] = g;
dest[i + 2] = b;
dest[i + 3] = a;
}

return dest;
}

但是,理想情况下我想使用字节移位构建 RGBA 值(这是微不足道的部分),但我的问题是如何将这样的 uint32 数字放入 dest (这必须是一个 Uint8Array ,理想情况下甚至与 src 相同,以便进行就地更改)。

我的意思是,在 C 中,一旦定义了 uint32_t rgbaColor,我就可以 memwrite 或将 int 分配给数组索引,溢出将完成其余的工作。但是我该如何在 JS 中做到这一点呢?

<小时/>

编辑:经过一些测试,看起来最初的提案实际上仍然是最快的

function argbToRgbaDataView(src, inline=false) {
let dest = inline ? src : new Uint8Array(src.length);
let srcView = new DataView(src.buffer);
let destView = new DataView(dest.buffer);

for (let i = 0; i < src.length; i += 4) {
let argb = srcView.getUint32(i);
let rgba = (argb & 0x00FFFFFF) << 8 |
(argb & 0xFF000000) >>> 24;
destView.setUint32(i, rgba);
}

return dest;
}

function argbToRgbaDataViewInline(src) {
return argbToRgbaDataView(src, true);
}

function argbToRgbaSwap(src, inline=false) {
let dest = inline ? src : new Uint8Array(src.length);

for (let i = 0; i < src.length; i += 4) {
let a = src[i]
let r = src[i + 1]
let g = src[i + 2]
let b = src[i + 3]

dest[i] = r;
dest[i + 1] = g;
dest[i + 2] = b;
dest[i + 3] = a;
}

return dest;
}

function argbToRgbaSwapInline(src) {
return argbToRgbaSwap(src, true);
}

function argbToRgbaSwapNoVars(src, inline = false) {
let dest = inline ? src : new Uint8Array(src);

for (let i = 0; i < src.length; i += 4) {
let a = src[i]

dest[i] = src[i + 1];
dest[i + 1] = src[i + 2];
dest[i + 2] = src[i + 3];
dest[i + 3] = a;
}

return dest;
}

function argbToRgbaSwapNoVarsInline(src) {
return argbToRgbaSwapNoVars(src, true);
}

// From https://stackoverflow.com/a/60639510/210151
function argb2rgbaStackOverflow(inArr) {
return inArr.reduce((a, c, i, t) => {
if (i % 4 === 0) {
let [A, R, G, B] = t.slice(i, i + 4)
a.push(R, G, B, A)
}
return a
}, [])
}

function measureFunction(func) {
let preTime = new Date().getTime();
let ret = func.call(...arguments);
console.log(`Calling ${func.name} took ${new Date().getTime() - preTime}ms`);
return ret;
}

function createRandomArray(size) {
return new Uint8Array(size).fill().map((a, i) =>
a = i).sort(() => Math.random() - 0.5);
}

function iconSizeToBytes(iconSize) {
const bytesPerPixel = 4;
return iconSize * iconSize * bytesPerPixel;
}

// This is to add support to console.log to gjs
try {
console;
} catch(e) {
window.console = {
log: function() { print(...arguments) },
};
}

let allSizes = [
iconSizeToBytes(32),
iconSizeToBytes(64),
iconSizeToBytes(512),
iconSizeToBytes(1024),
iconSizeToBytes(2048),
];

for (let size of allSizes) {
console.log(`Creating random array of ${size/(1024 * 1024)}Mbyte...`);
let randomArray = measureFunction(createRandomArray, size);

measureFunction(argbToRgbaDataView, randomArray);
measureFunction(argbToRgbaDataViewInline, randomArray);
measureFunction(argbToRgbaSwap, randomArray);
measureFunction(argbToRgbaSwapInline, randomArray);
measureFunction(argbToRgbaSwapNoVars, randomArray);
measureFunction(argbToRgbaSwapNoVarsInline, randomArray);
measureFunction(argb2rgbaStackOverflow, randomArray);

console.log('------------------------------------------------------');
}
<script src="https://rawgit.com/eu81273/jsfiddle-console/master/console.js"></script>

最佳答案

看起来在写这篇文章时我发现了 DataView 的创建这确实简化了我的生活!

所以问题可以通过以下方式解决:

function argbToRgba(src) {
let dest = new Uint8Array(src.length);
let srcView = new DataView(src.buffer);
let destView = new DataView(dest.buffer);

for (let i = 0; i < src.length; i += 4) {
let argb = srcView.getUint32(i);
let rgba = (argb & 0x00FFFFFF) << 8 |
(argb & 0xFF000000) >>> 24;
destView.setUint32(i, rgba);
}

return dest;
}

使用let dest = src;也可以内联完成更改。

关于ARGB 到 RGBA 数组转换的 JavaScript 优化版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60638559/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com