使用 JS、JQuery 或 HTML5 调整图像大小

Posted

技术标签:

【中文标题】使用 JS、JQuery 或 HTML5 调整图像大小【英文标题】:Resizing Image Using JS, JQuery or HTML5 【发布时间】:2017-07-22 19:56:40 【问题描述】:

我目前正在使用bootstrap-wysiwyg 富文本编辑器。这允许用户将图像文件拖到编辑器中,这很棒,但是我想动态调整此图像的大小。我相信我已经在 bootstrap-wysiwyg.js 中找到了我应该尝试调整图像大小的位置,然后它才会显示在编辑器中,然后在用户单击提交时发布到 php 页面。

通过阅读其他 *** 帖子,似乎首选的方法是使用 html5 的画布功能。我也有可用的 jQuery。该解决方案必须支持的唯一浏览器是当前版本的 Chrome 或 Firefox。

我相信我已经为这个调整大小功能找到了一个很好的切入点:

function (files) 
  editor.focus();
  $.each(files, function (idx, fileInfo) 
    if (/^image\//.test(fileInfo.type)) 

      // ENTRYPOINT: attempt to resize

      $.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) 
        execCommand('insertimage', dataUrl);
        editor.trigger('image-inserted');
      ).fail(function (e) 
        options.fileUploadError("file-reader", e);
      );
     else 
      options.fileUploadError("unsupported-file-type", fileInfo.type);
    
  );
,

上面的代码预先存在于 bootstrap-wysiwg 库中。我在想我可以以某种方式获取 fileInfo 对象,将其转换为 Image 对象,调整大小,生成图像的 dataurl 版本,然后调用:

execCommand('insertimage', dataUrl);
editor.trigger('image-inserted');

我觉得这将消除对当前包含这两个函数调用的 $.when 函数的需要。

我尝试过集成 StackExchange 中的其他示例,this one 尤其有前途,但我对 JS 的理解还不够好,无法正确地适应我的需求。

我意识到我可以在 POST/上传后调整图像服务器端的大小,但这并不可取,因为目标是自动调整拖入编辑器窗口的非常大的图像的大小,使其更易于管理正在使用编辑器窗口并且没有在所有方向上填满整个编辑器窗口的最终用户。

生成图像的质量并不是那么重要,所以我不关心那些类型的优化以及其他地方已经提到的那些。

【问题讨论】:

【参考方案1】:

我最近做了一个辅助项目 (kropimg.com),它做了类似的事情 - 完全使用 canvas 在客户端调整图像大小。

不过你有更多选择:

客户端唯一的方式

如果您坚持在客户端做所有事情,您将需要使用画布来调整图像的大小 - 因为您怀疑将 $.when 部分替换为来自 this answer 的函数调用。 (你可能需要先通过img = readFileIntoDataUrl(fileInfo);

服务器端的唯一方式

我不知道你是否知道这一点,但你不能直接用文件对象进行 ajax 调用。您应该使用 FileReader 接口来读取内容,首先要做的是异步。请参阅this answer。 在服务器上完成调整大小后,您可以将图像的 url 返回到前面。同时,您可以显示微调器(就像 Gmail 一样)。

编辑:意识到你不想要服务器端方法

混合方式

另一种方法是使用 CSS/JS 调整图像大小,然后在上传后,将新尺寸发送到服务器并在那里调整大小(使用 GD 或 ImageMagik)。只需使用 jQuery 在该图像上设置一些 CSS。如果我是你,我会采用这种方法。尽管您说您不关心质量,但是将大图像的大小调整到 25% 以下可能看起来很丑(很多锯齿)。这种方法的缺点是上传大图需要一段时间。

希望这会有所帮助。

【讨论】:

感谢您的回复。我决定使用仅客户端选项。这是最适合我的需求的解决方案,因为它用一块石头杀死了两只鸟:1)较小的图像尺寸为用户带来更易于管理的编辑器窗口。 2)上传前较小的图像尺寸导致所需的上传带宽更少这不是商业项目,因此对于我的用例而言,客户端计算机上的资源负载并不重要。我将在下面发布我的最终解决方案,但是,我觉得我应该接受您的回答,因为它提供了丰富的信息并引导我找到我的解决方案?这是正确的做法吗?【参考方案2】:

我选择使用纯客户端选项来解决我的问题。这主要是由于我的用例的特殊性。这不仅允许我在将图像插入“bootstrap-wysiwg 编辑器”之前缩小图像,还可以在图像上传到服务器之前减小图像的大小。我们的上传带宽非常低,因此这是非常重要的一点。我的用例不关心旧版浏览器支持和客户端资源使用情况。

我能够使用此 answer 提供的调整大小功能,为了便于访问,我在下面复制了该功能:

// resize function
function imageToDataUri(img, width, height) 

    // create an off-screen canvas
    var canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d');

    // set its dimension to target size
    canvas.width = width;
    canvas.height = height;

    // draw source image into the off-screen canvas:
    ctx.drawImage(img, 0, 0, width, height);

    // encode image to data-uri with base64 version of compressed image
    return canvas.toDataURL();

然后我能够对现有的“bootstrap-wysiwyg.js”进行一些细微的更改以集成调整大小功能:

insertFiles = function (files) 
  editor.focus();
  $.each(files, function (idx, fileInfo) 
    if (/^image\//.test(fileInfo.type)) 
      // resize
      var img = new Image();

      img.onload = function() 
        // TODO: add some error checking and gracefully handle errors
        var dataUrl = imageToDataUri(img, 300, 200);

        execCommand("insertimage", dataUrl);
        editor.trigger("image-inserted");

        URL.revokeObjectURL(img.src)
      
      img.src = URL.createObjectURL(fileInfo);
     else 
      options.fileUploadError("unsupported-file-type", fileInfo.type);
    
  );

这对我的目的非常有用,尽管我可能会对其进行修改,使其仅调整大于特定阈值的图像大小,并对其进行更改以保留原始图像的纵横比。

【讨论】:

以上是关于使用 JS、JQuery 或 HTML5 调整图像大小的主要内容,如果未能解决你的问题,请参考以下文章

按比例调整图像大小以适合 HTML5 画布

使用 Html5 的 JQuery 随机播放效果 [Canvas +CSS +JS]

HTML5 Canvas 调整图片大小 点击放大

如何创建带有“可悬停”区域的图像,在 jQuery 或 HTML5 中显示附加信息

用html5或js功能或css实现特定方框内图像保存为图片功能。

html5、js 和 css3 图像裁剪工具 [关闭]