【问题标题】:Posting large Base64 strings to a server将大型 Base64 字符串发布到服务器
【发布时间】:2015-08-18 19:32:06
【问题描述】:

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

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

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

  • 降低画布中图像的分辨率
  • 降低画布创建的图像的分辨率
  • 缩小画布的颜色范围

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

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

【问题讨论】:

  • The timeout limit is currently set at 20 seconds, which I would expect is more than enough. 本地 ... 是的 ... 例如通过 ADSL ... 你需要 40 秒来确定
  • 您的服务器端设置(语言)是什么?如果是 PHP,你应该已经在 SO 上找到了很多关于文件上传限制及其配置的信息。
  • 我正在使用 PHP,但这不是文件大小限制问题。我们的服务器上传限制是 20MB,而这些文件没有达到任何接近这个限制(通常在 2-3MB 之间)。

标签: javascript ajax html image canvas


【解决方案1】:

• 缩小画布的颜色范围

您可以使用canvas.getImageDatacanvas.putImageData 来执行此操作。

这是首先用一组随机颜色绘制画布的示例

<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 图像格式以及哪种颜色优化将有助于弄清楚“如何”这样做,以便我减小图像大小。


警告:前面的警告框。不要惊慌。

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>

【讨论】:

    猜你喜欢
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 2014-11-23
    • 2011-06-30
    相关资源
    最近更新 更多