我正在尝试通过ajax将大型base64(大约3500000个字符长)发布到服务器端脚本,该脚本将base64转换为图像。问题是,有时发布会超时,服务器从未收到 Base64。超时限制目前设置为 20 秒,我认为这已经足够了。
我真的不想进一步缩小图像,因为它的分辨率已经比我想要的要低(发布的图像将被物理打印,因此需要相当高分辨率)。
我能想到的潜在解决方案是:
- 降低 Canvas 内图像的分辨率
- 降低 Canvas 创建的图像的分辨率
- 减少 Canvas 的颜色范围
最后一个是我最感兴趣的,因为我已经尽可能地实现了其他两个,但我不知道如何去做。
任何有关如何解决此问题的建议或解决方案将不胜感激。谢谢。
最佳答案
• Reduce the colour range of the canvas
您可以使用canvas.getImageData
和canvas.putImageData
来执行此操作。
这是首先使用一组随机颜色绘制 Canvas 的示例
<canvas id="before" width="300" height="200"></canvas>
var bcanvas = document.getElementById('before')
var bctx = bcanvas.getContext("2d");
for (var i = 0; i < 300; i = i + 3) {
var r = parseInt(Math.random() * 256)
var g = parseInt(Math.random() * 256)
var b = parseInt(Math.random() * 256)
bctx.fillStyle = "rgba(" + r + ", " + g + ", " + b + ", 1)";
bctx.fillRect(i, 0, 3, 200);
}
alert(bcanvas.toDataURL().length);
然后我们循环遍历像素,减少颜色数量(这里我们只是将每个像素的 r g 和 b 值除以 16,向下舍入,然后将其缩放到 255,最终每个像素得到约 16 个不同的值r g 和 b 分别代替 255)
var imgData = bctx.getImageData(0, 0, 300, 200);
var pixels = imgData.data;
// if a pixel is slightly red make it full red, same for blue and green
for (var nPixel = 0; nPixel < pixels.length; nPixel += 4) {
pixels[nPixel] = parseInt(pixels[nPixel] / 16) * 16;
pixels[nPixel + 1] = parseInt(pixels[nPixel + 1] / 16) * 16;
pixels[nPixel + 2] = parseInt(pixels[nPixel + 2] / 16) * 16;
}
var acanvas = document.getElementById('after')
var actx = acanvas.getContext("2d");
actx.putImageData(imgData, 0, 0);
alert(acanvas.toDataURL().length);
导致 DataURL 长度减少约 17%。
请注意,这只是“如何做”。您可能需要阅读 png 图像格式以及哪种颜色优化将有利于弄清楚“如何”做到这一点,以便减小图像大小。
<小时/>警告:前面有警报框。不要 panic 。
var bcanvas = document.getElementById('before')
var bctx = bcanvas.getContext("2d");
for (var i = 0; i < 300; i = i + 3) {
var r = parseInt(Math.random() * 256)
var g = parseInt(Math.random() * 256)
var b = parseInt(Math.random() * 256)
bctx.fillStyle = "rgba(" + r + ", " + g + ", " + b + ", 1)";
bctx.fillRect(i, 0, 3, 200);
}
alert(bcanvas.toDataURL().length);
var imgData = bctx.getImageData(0, 0, 300, 200);
var pixels = imgData.data;
// if a pixel is slightly red make it full red, same for blue and green
for (var nPixel = 0; nPixel < pixels.length; nPixel += 4) {
pixels[nPixel] = parseInt(pixels[nPixel] / 16) * 16;
pixels[nPixel + 1] = parseInt(pixels[nPixel + 1] / 16) * 16;
pixels[nPixel + 2] = parseInt(pixels[nPixel + 2] / 16) * 16;
}
var acanvas = document.getElementById('after')
var actx = acanvas.getContext("2d");
actx.putImageData(imgData, 0, 0);
alert(acanvas.toDataURL().length);
<canvas id="before" width="300" height="200"></canvas>
<br />
<canvas id="after" width="300" height="200"></canvas>
关于javascript - 将大型 Base64 字符串发布到服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32069992/