我试图通过ajax将大型base64(大约350万个字符长)发布到将base64转换为图像的服务器端脚本。问题是,有时邮件超时,服务器永远不会收到base64。超时限制目前设置为20秒,我预计这是绰绰有余。
我真的不想进一步缩小图像,因为它的分辨率已经低于我想要的分辨率(发布的图像将被物理打印,因此需要相当高的分辨率)。
我能想到的潜在解决方案是:
最后一个是我最感兴趣的那个,因为我已经尽可能地实现了其他两个,但我不知道该怎么做。
任何有关如何解决此问题的建议或解决方案都将受到赞赏。感谢。
答案 0 :(得分:1)
•缩小画布的颜色范围
您可以使用canvas.getImageData
和canvas.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>