javascript - 将大型 Base64 字符串发布到服务器

标签 javascript ajax html image canvas

我正在尝试通过ajax将大型base64(大约3500000个字符长)发布到服务器端脚本,该脚本将base64转换为图像。问题是,有时发布会超时,服务器从未收到 Base64。超时限制目前设置为 20 秒,我认为这已经足够了。

我真的不想进一步缩小图像,因为它的分辨率已经比我想要的要低(发布的图像将被物理打印,因此需要相当高分辨率)。

我能想到的潜在解决方案是:

  • 降低 Canvas 内图像的分辨率
  • 降低 Canvas 创建的图像的分辨率
  • 减少 Canvas 的颜色范围

最后一个是我最感兴趣的,因为我已经尽可能地实现了其他两个,但我不知道如何去做。

任何有关如何解决此问题的建议或解决方案将不胜感激。谢谢。

最佳答案

• Reduce the colour range of the canvas

您可以使用canvas.getImageDatacanvas.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/

相关文章:

javascript - 在字符串中的字符之间添加空格

javascript - 如何使用 maxmind javascript 获取信息的 ip

javascript - 如何在ajax调用之前定义变量

html - CSS 反转悬停动画

javascript - 找到 2 个具有非唯一 ID 的元素

html - 如何使用前/后元素切片背景颜色

javascript - CSS三 Angular 形在两种颜色之间过渡

javascript - CORS 错误取决于图像参数设置顺序

javascript - 全日历 JSON/AJAX

php - 有些东西让我的页面多次执行 Ajax 调用... [读取 : I've never been more frustrated with something so 'simple' in my life]