【问题标题】:JS-Convert an Image object to a jpeg fileJS-将Image对象转换为jpeg文件
【发布时间】:2018-06-03 11:35:06
【问题描述】:

所以,我有一个用于上传图片的用户输入。这是一个简单的例子:

function handleImage(e){
    var reader = new FileReader();
    reader.onload = function(event){
        var img = new Image();
        img.onload = function(){
            console.log (img);
        }
        img.src = event.target.result;
    }
    reader.readAsDataURL(e.target.files[0]);     
}
<input type="file" onchange="handleImage(event)"><br>

如您所见,我在console 上显示Image ()。我想把这个Image转换成jpg文件。

我知道如何获取图片的像素,但是将它发送到服务器完全是疯狂的:它太大了!

我也尝试访问存储在计算机中的 jpg 文件,但我没有实现任何目标。

我发现的唯一方法是使用form 发送它,如下所示:

<form action="anything.php" method="post" enctype="multipart/form-data">
    <input type="file" name="fileToUpload" id="fileToUpload">
</form>   

在 PHP 中:

$_FILES["fileToUpload"]["tmp_name"]

为什么不用 JS?

我的最终目标是使用 AJAX 发送 jpg 文件。

如果您有任何问题,请告诉我。

【问题讨论】:

    标签: javascript image imagejpeg


    【解决方案1】:

    最简单的方法是使用画布元素,然后调用下载操作,允许用户选择保存图像的位置。

    您提到图像很大,但没有提到多大 - 请注意,使用画布时,当图像源开始触及像素大小的 8k 区域附近时,您也会遇到限制。

    一个简化的例子(IE 需要一个用于 toBlob() 的 polyfill)。:

    • 通过输入加载图像源
    • 通过URL.createObjectURL()直接使用File blob作为图像源
    • 加载后,创建一个临时画布,设置画布大小 = 图像大小并在图像中绘制
    • 使用toBlob()(在内存和性能方面更高效,并且不需要转码到/从 Base64 转码)来获得Blob
    • 我们会将Blob 转换为File(一个子对象,它将引用相同的内存),因此我们还可以提供一个文件名以及(重要的!)一个二进制mime-type。

    由于最后一步的 mime 类型是二进制的,因此浏览器将调用另存为对话框。

    document.querySelector("input").onchange = function() {
      var img = new Image;
      img.onload = convert;
      img.src = URL.createObjectURL(this.files[0]);
    };
    
    function convert() {
      URL.revokeObjectURL(this.src);             // free up memory
      var c = document.createElement("canvas"),  // create a temp. canvas
          ctx = c.getContext("2d");
      c.width = this.width;                      // set size = image, draw
      c.height = this.height;
      ctx.drawImage(this, 0, 0);
      
      // convert to File object, NOTE: we're using binary mime-type for the final Blob/File
      c.toBlob(function(blob) {
        var file = new File([blob], "MyJPEG.jpg", {type: "application/octet-stream"});
        window.location = URL.createObjectURL(file);
      }, "image/jpeg", 0.75);  // mime=JPEG, quality=0.75
    }
    
    // NOTE: toBlob() is not supported in IE, use a polyfill for IE.
    &lt;label&gt;Select image to convert: &lt;input type=file&gt;&lt;/label&gt;

    更新:如果您只是在寻找新创建的 JPEG 的字符串(base-64 编码)版本,只需使用 toDataURL() 而不是 toBlob()

    document.querySelector("input").onchange = function() {
      var img = new Image;
      img.onload = convert;
      img.src = URL.createObjectURL(this.files[0]);
    };
    
    function convert() {
      URL.revokeObjectURL(this.src);             // free up memory
      var c = document.createElement("canvas"),  // create a temp. canvas
          ctx = c.getContext("2d");
      c.width = this.width;                      // set size = image, draw
      c.height = this.height;
      ctx.drawImage(this, 0, 0);
      
      // convert to File object, NOTE: we're using binary mime-type for the final Blob/File
      var jpeg = c.toDataURL("image/jpeg", 0.75);  // mime=JPEG, quality=0.75
      console.log(jpeg.length)
    }
    &lt;label&gt;Select image to convert: &lt;input type=file&gt;&lt;/label&gt;

    【讨论】:

    • 感谢您的工作。但是我没有直接访问 jpeg 文件。我真正想要的是将您在变量中创建的文件的值作为字符串值。
    • @S.P.H.I.N.X 只需将 c.toBlob 替换为同步的 c.toDataURL("image/jpeg")。
    • 如果您希望 PHP 将其识别为文件,则应使用 FormData 和 blob 上传它。并为自己节省一些带宽,无需更改 mime 类型
    【解决方案2】:

    客户端的 JavaScript 无法保存文件。 您有多种选择:

    1. &lt;canvas&gt; 元素上渲染图像。这样就可以右键保存->保存图片
    2. 将图像插入为&lt;img&gt; 元素。这样就可以右键保存->保存图片
    3. 将图像数据作为 base64 字符串发送到服务器。在那里进行处理
    4. 使用 PHP 或 Node.js 等服务器端语言来保存文件

    长话短说,您必须使用一些服务器端逻辑来将文件保存在磁盘上

    【讨论】:

      猜你喜欢
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      • 2019-01-14
      • 2012-12-22
      • 1970-01-01
      • 2016-11-25
      • 1970-01-01
      • 2020-08-03
      相关资源
      最近更新 更多