canvas 太大了(6000*6000)然后在手机上 toBlob 的时候,手机浏览器会崩溃,获取不到 blob object,有什么办法处理吗?

2019-01-25 09:41:24 +08:00
 coolair

用 javascrip 临时创建一个 canvas 然后用 fabric 载入数据,想生成指定大小的图片,传给服务器,但是在手机上,当指定图片太大时,手机浏览器就崩溃了,有什么好办法吗?

代码如下,代码在 PC 上没有问题,但是在手机上,alert(blob) 就是 null,但是把 width 和 height 缩小到 2000 以内就没问题:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <script src="https://cdn.staticfile.org/fabric.js/2.6.0/fabric.min.js"></script>
    <script>
        var text_json = '{"version":"2.6.0","objects":[{"type":"i-text","version":"2.6.0","originX":"center","originY":"center","left":2689.368365180467,"top":2343.557898089172,"width":53.26,"height":45.2,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"text":"AAAAAAAAAAAAAAA","fontSize":483.4819532908705,"fontWeight":"normal","fontFamily":"Times New Roman","fontStyle":"normal","lineHeight":1.16,"underline":false,"overline":false,"linethrough":false,"textAlign":"left","textBackgroundColor":"","charSpacing":0,"centeredRotation":true,"hasControls":false,"borderColor":"red","styles":{}}],"centeredRotation":false}';
        
        var temp = document.createElement('canvas');
        var canvas = new fabric.Canvas(temp, {width: 6000, height: 6000});
        canvas.loadFromJSON(text_json, canvas.renderAll.bind(canvas));
        temp.toBlob(function(blob) {
            alert(blob);  // 这里在手机上显示 null,在 pc 上没有问题
            var newImg = document.createElement('img');
            url = URL.createObjectURL(blob);

            newImg.src = url;
            newImg.style.height = '600px';
            document.body.appendChild(newImg);
        });
    </script>
</body>
</html>
2321 次点击
所在节点    问与答
13 条回复
momocraft
2019-01-25 09:52:42 +08:00
也许分成几块小的? 不过这个例子中为什么不直接传 JSON 呢
coolair
2019-01-25 09:53:45 +08:00
@momocraft 传 json 给服务器服务器没办法生成图片
GDC
2019-01-25 10:06:22 +08:00
@coolair 要不来解决服务器为啥不能生成图片…?感觉比 canvas 这问题好解决,而且解决了还可以大幅降低数据传输量,你知道 6000×6000 无压缩的图片有多大么…
coolair
2019-01-25 10:14:29 +08:00
GDC
2019-01-25 10:43:26 +08:00
@coolair 看看 https://stackoverflow.com/questions/6081483/maximum-size-of-a-canvas-element 这个问题,第一个答案的评论里有提到 iOS 上的最大尺寸,可以作为参考
MozzieW
2019-01-25 10:46:37 +08:00
6000*6000*4/1024/1024 = 137.329101563 (MB)
算一下, 就算 App 有 300M 内存, 这个 Canvas 就占了差不多一半. 后面 toBlob 再耗一点, 应该内存就爆了(OOM)?
无压缩的 RGB 位图, 不管里面多少个字, 占用内存都一样. 什么情景几个字要用 6000*6000 来显示?
daben1990
2019-01-25 10:51:47 +08:00
先上传。。。
coolair
2019-01-25 10:58:04 +08:00
@MozzieW 你说的对啊,看来还是我的方式有问题。
GDC
2019-01-25 11:28:56 +08:00
@MozzieW @coolair 本来我在 #3 提到图片可能太大,但后来实践了一下其实并没那么大,可能楼主的实际应用会大一些,但主贴给出的代码我运行了一下,console.log() 打印出来的 blob size 只有 893186,也就是 1M 还不到~ 于是转而去搜 canvas 尺寸限制的可能性,还真有…
coolair
2019-01-25 12:22:06 +08:00
@GDC 是啊,现在不知道怎么办了。
joyme
2019-01-25 13:48:39 +08:00
浏览器对 canvas 的大小有限制,不同的浏览器限制还不同,比如 firefox 比 chrome 的限制就严格的多。

要么你考虑减少 canvas 的大小,或者分成多个部分绘制。

要么就是服务器渲染。服务器渲染这一块可以直接使用绘图库去绘制。或者是使用无头浏览器的方案也很方便
sharkrice
2019-01-25 13:51:55 +08:00
我记得同事也有做类似的,最后分成几块绘制
baze
2019-01-25 15:33:21 +08:00
用瓦片分别绘制

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/530463

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX