PixiJS:如何验证通过Assets.load加载URL图片后的有效纹理?
如何验证PixiJS加载的纹理是否包含有效图像?
我用PixiJS v7.4.2加载维基百科的图片资源,完全按照官方文档来做,但有些过时的URL加载后得到的纹理是空白的,加到视口后根本看不到图像。我写了个函数在创建Sprite前验证图片源,但还是解决不了问题:
async validate_image_source(wiki_img_url: string): Promise<boolean> { try { const texture = await Assets.load(wiki_img_url); return texture !== null && texture.orig !== null && texture.baseTexture !== null; } catch (error) { console.log("Failed to load image:", error); return false; } }
问题出在,就算URL返回的是无效资源(比如占位图、空白图或者已经被删除的图),上面的验证条件还是会返回true——因为texture、orig和baseTexture这些对象依然存在,只是没有有效像素数据而已。
有效的验证方法
1. 检查纹理的实际尺寸
无效的空白纹理通常宽高会是0或者异常值,直接通过baseTexture的宽高判断最直接:
async validate_image_source(wiki_img_url: string): Promise<boolean> { try { const texture = await Assets.load(wiki_img_url); const baseTex = texture.baseTexture; // 先确认基础纹理存在,且宽高都大于0 if (!baseTex || baseTex.width <= 0 || baseTex.height <= 0) { return false; } return true; } catch (error) { console.log("加载图片失败:", error); return false; } }
2. 进一步检查像素内容(针对占位图)
如果遇到维基百科那种“图片已删除”的占位图(通常是白色或灰色的空白图),光看尺寸不够,得检查像素:
async validate_image_source(wiki_img_url: string): Promise<boolean> { try { const texture = await Assets.load(wiki_img_url); const baseTex = texture.baseTexture; if (!baseTex || baseTex.width <= 0 || baseTex.height <= 0) { return false; } // 创建临时画布,绘制纹理后取像素判断 const canvas = document.createElement('canvas'); canvas.width = baseTex.width; canvas.height = baseTex.height; const ctx = canvas.getContext('2d'); if (!ctx) return false; ctx.drawImage(baseTex.source as HTMLImageElement, 0, 0); // 取左上角第一个像素的RGBA值 const pixel = ctx.getImageData(0, 0, 1, 1).data; const [r, g, b, a] = pixel; // 维基百科的删除占位图一般是全白或全灰,根据实际情况调整判断条件 if (a === 0 || (r === 255 && g === 255 && b === 255)) { return false; } return true; } catch (error) { console.log("加载图片失败:", error); return false; } }
3. 监听纹理加载的错误事件
除了try/catch,还可以直接监听baseTexture的error事件,捕获加载过程中的资源错误:
async validate_image_source(wiki_img_url: string): Promise<boolean> { return new Promise((resolve) => { const baseTex = new PIXI.BaseTexture(wiki_img_url); // 加载失败触发 baseTex.on('error', () => { baseTex.destroy(); resolve(false); }); // 加载完成后验证尺寸 baseTex.on('loaded', () => { const isValid = baseTex.width > 0 && baseTex.height > 0; baseTex.destroy(); resolve(isValid); }); }); }
内容的提问来源于stack exchange,提问作者richbox
相关产品推荐
相关产品推荐

