Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在HTML5画布中处理大型图像_Javascript_Image_Canvas_Html5 Canvas - Fatal编程技术网

Javascript 在HTML5画布中处理大型图像

Javascript 在HTML5画布中处理大型图像,javascript,image,canvas,html5-canvas,Javascript,Image,Canvas,Html5 Canvas,我有一个15000x15000像素的矢量图像,我想用作画布项目的背景。我需要能够剪切一张图像,并将其作为背景快速、频繁地绘制(在requestAnimationFrame中) 要绘制我正在使用的图像所需的扇区 const xOffset = (pos.x - (canvas.width / 2)) + config.bgOffset + config.arenaRadius; const yOffset = (pos.y - (canvas.height / 2)) + config.bgOff

我有一个15000x15000像素的矢量图像,我想用作画布项目的背景。我需要能够剪切一张图像,并将其作为背景快速、频繁地绘制(在
requestAnimationFrame
中)

要绘制我正在使用的图像所需的扇区

const xOffset = (pos.x - (canvas.width / 2)) + config.bgOffset + config.arenaRadius;
const yOffset = (pos.y - (canvas.height / 2)) + config.bgOffset + config.arenaRadius;
c.drawImage(image, xOffset, yOffset, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height);
计算所需背景面积并绘制图像。这一切都很好,但重画是缓慢的,第一次绘制更慢

加载这个巨大的图像看起来很可笑,而且性能也很慢。如何减少文件大小或以其他方式提高性能


编辑:以全尺寸绘制如此大的图像没有合理的解决方案。因为背景是一个重复的模式,所以我当前的解决方案是使用一个模式“单元格”并多次绘制。

我强烈建议使用EaselJS将多个/大型对象渲染到HTML画布。该库支持向量缓存、webgl等

以下是一个将多个矢量对象缓存到位图中的示例(单击复选框进行比较):


您应该能够以相同的方式处理背景向量。只需缓存对象,让软件处理所有繁重的工作。

15000px 15000px确实很大

GPU必须将其作为原始RGB数据存储在其内存中(我不记得确切的数学运算,但我认为它类似于宽度x高度x 3字节,即675MB,这比大多数普通GPU所能处理的要多)。
再加上你可能拥有的所有其他图形,你的GPU将被迫放下你的大图像,并在每一帧再次抓取它

为了避免这种情况,您最好将大图像分割成多个小图像,并在每帧中多次调用
drawImage
。这样,在最坏的情况下,GPU将只需要获取所需的部分,在最好的情况下,它将已经在其内存中

这里是一个粗略的概念证明,它将把一个5000*5000px的svg图像分割成250*250px的分片。当然,你必须根据自己的需要调整它,但它可能会给你一个想法

console.log('generatingimage…');
var bigImg=新图像();
bigimgsrc=URL.createObjectURL(generateBigImage(50005000));
bigimgonload=init;
函数splitBigImage(img、maxSize){
如果(!maxSize | | typeof maxSize!=“number”)maxSize=500;
var iw=img.naturalWidth,
ih=img.自然高度,
tw=数学最小值(最大值,iw),
th=数学最小值(最大尺寸,ih),
tileCols=Math.ceil(iw/tw),//我们将有多少列
tileRows=Math.ceil(ih/th),//我们将有多少行
瓷砖=[],
r、 c、帆布;
//在不同的画布上绘制图像的每个部分
对于(r=0;rbg.width-ctx.canvas.width){
dx*=-1;
x=bg.width-ctx.canvas.width-1;
}
if(y<0){
dy*=-1;
y=1;
}
如果(y>bg.height-ctx.canvas.height){
dy*=-1;
y=bg.height-ctx.canvas.height-1;
}
clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
如果(已检查){
//这就是你所说的
背景图(ctx,x,y);
}
否则{
ctx.drawImage(bigImg,-x,-y);
}
请求动画帧(anim);
}
函数changeDirection(){
dx=(Math.random())*5*数学符号(dx);
dy=(Math.random())*5*Math.sign(dy);
}
setTimeout(函数(){console.clear();},1000);
}
//生成宽度*高度的伪随机svg图像
函数生成器框架(宽度、高度){
var str='',
x、 y;
对于(y=0;y
绘制拆分

您的画布有多大?此外,SVG?@MátéSafranka中的矢量图像可以根据屏幕大小进行缩放。我设计的本机尺寸是1920x1080(实际窗口为1920x974)。我在亲和力设计师的背景下,所以我可以出口SVG。我冒险在我的信心区外,B。