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

时间:2015-08-18 10:34:30

标签: javascript ajax html5 image canvas

我试图通过ajax将大型base64(大约350万个字符长)发布到将base64转换为图像的服务器端脚本。问题是,有时邮件超时,服务器永远不会收到base64。超时限制目前设置为20秒,我预计这是绰绰有余。

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

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

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

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

任何有关如何解决此问题的建议或解决方案都将受到赞赏。感谢。

1 个答案:

答案 0 :(得分: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);

然后我们遍历像素,减少颜色数量(这里我们只是将每个像素的rg和b值除以16,将其向下舍入然后将其缩放到255,最后得到每个像素的~16个不同的值rg和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>