javascript - js修改title




如何在浏览器中通过Javascript压缩图像? (4)

TL; DR;

有没有办法在上传之前直接在浏览器端压缩图像(主要是jpeg,png和gif)? 我很确定JavaScript可以做到这一点,但我找不到实现它的方法。


这是我想要实现的完整场景:

  • 用户进入我的网站,并通过input type="file"元素选择图像,
  • 这个图像是通过JavaScript检索的,我们做了一些验证,如正确的文件格式,最大文件大小等,
  • 如果一切正常,页面上会显示图像的预览,
  • 用户可以进行一些基本操作,例如将图像旋转90°/ -90°,按照预定义的比例裁剪等,或者用户可以上传另一张图像并返回步骤1,
  • 当用户满意时,编辑后的图像会被压缩并在本地“保存”(不保存到文件中,但在浏览器内存/页面中), -
  • 用户填写表格,其中包含姓名,年龄等数据,
  • 用户单击“完成”按钮,然后将包含数据+压缩图像的表单发送到服务器(不带AJAX),

直到最后一步的完整过程应该在客户端完成,并且应该与最新的Chrome和Firefox,Safari 5+和IE 8+兼容。 如果可能,只应使用JavaScript(但我很确定这是不可能的)。

我现在没有编码任何东西,但我已经考虑过了。 可以通过File API在本地读取文件 ,可以使用Canvas元素完成图像预览和编辑,但我找不到一种方法来执行图像压缩部分

根据html5please.comcaniuse.com ,支持这些浏览器非常困难(感谢IE),但可以使用FlashCanvasFileReader FlashCanvas来完成。

实际上,目标是减小文件大小,因此我将图像压缩视为一种解决方案。 但是,我知道上传的图像将在我的网站上显示,每次都在同一个地方,我知道这个显示区域的尺寸(例如200x400)。 因此,我可以调整图像大小以适应这些尺寸,从而减小文件大小。 我不知道这种技术的压缩比是多少。

你怎么看 ? 你有什么建议告诉我吗? 你知道在JavaScript中压缩图像浏览器的方法吗? 谢谢你的回复。


@PsychoWoods的回答很好。 我想提供自己的解决方案。 此Javascript函数获取图像数据URL和宽度,将其缩放到新宽度,并返回新的数据URL。

// Take an image URL, downscale it to the given width, and return a new image URL.
function downscaleImage(dataUrl, newWidth, imageType, imageArguments) {
    "use strict";
    var image, oldWidth, oldHeight, newHeight, canvas, ctx, newDataUrl;

    // Provide default values
    imageType = imageType || "image/jpeg";
    imageArguments = imageArguments || 0.7;

    // Create a temporary image so that we can compute the height of the downscaled image.
    image = new Image();
    image.src = dataUrl;
    oldWidth = image.width;
    oldHeight = image.height;
    newHeight = Math.floor(oldHeight / oldWidth * newWidth)

    // Create a temporary canvas to draw the downscaled image on.
    canvas = document.createElement("canvas");
    canvas.width = newWidth;
    canvas.height = newHeight;

    // Draw the downscaled image on the canvas and return the new data URL.
    ctx = canvas.getContext("2d");
    ctx.drawImage(image, 0, 0, newWidth, newHeight);
    newDataUrl = canvas.toDataURL(imageType, imageArguments);
    return newDataUrl;
}

此代码可以在您拥有数据URL的任何地方使用,并且需要缩小图像的数据URL。



简而言之:

  • 使用带有.readAsArrayBuffer的HTML5 FileReader API读取文件
  • 使用文件数据创建e Blob并使用window.URL.createObjectURL(blob)获取其URL
  • 创建新的Image元素并将其src设置为文件blob url
  • 将图像发送到画布。 画布大小设置为所需的输出大小
  • 通过canvas.toDataURL(“image / jpeg”,0.7)从画布返回缩小的数据(设置自己的输出格式和质量)
  • 将新的隐藏输入附加到原始表单,并将dataURI图像基本上作为普通文本传输
  • 在后端,读取dataURI,从Base64解码,然后保存

来源: code


编辑:根据Mr Me对此答案的评论,看起来压缩现在可用于JPG / WebP格式(请参阅https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL ) 。

据我所知,你无法使用画布压缩图像,相反,你可以调整它的大小。 使用canvas.toDataURL不会让您选择要使用的压缩率。 您可以查看完全符合您要求的canimage: https://github.com/nfroidure/CanImage/blob/master/chrome/canimage/content/canimage.jshttps://github.com/nfroidure/CanImage/blob/master/chrome/canimage/content/canimage.js

实际上,通常只需调整图像大小以减小其大小即可,但如果您想要更进一步,则必须使用新引入的方法file.readAsArrayBuffer来获取包含图像数据的缓冲区。

然后,根据图像格式规范( http://en.wikipedia.org/wiki/JPEGhttp://en.wikipedia.org/wiki/Portable_Network_Graphics )使用DataView读取内容。

处理图像数据压缩会很困难,但尝试更糟糕。 另一方面,您可以尝试删除PNG标头或JPEG exif数据以使图像更小,这样做应该更容易。

您必须在另一个缓冲区上创建另一个DataWiew,并用过滤后的图像内容填充它。 然后,您只需使用window.btoa将图像内容编码为DataURI。

让我知道如果你实现类似的东西,将通过代码将是有趣的。





compression