首页 > 其他分享 >使用前端js库pica压缩图片

使用前端js库pica压缩图片

时间:2024-08-14 16:15:40浏览次数:13  
标签:const img 前端 elem js blob file pica con

pica

浏览器中的高质量图像大小调整

在浏览器中调整图像大小,无需像素化,速度相当快。自动选择最好的可用技术:webworkers、webassembly、createImageBitmap、纯JS。

简单使用

<script src="./plugins/pica.min.js"></script>

<script>
  function resizeImage(img_path, file_name) {
    const img = new Image();
    img.src = img_path;
    img.onload = function () {
      const canvas = document.createElement("canvas");
      canvas.width = img.width;
      canvas.height = img.height;

      const pica = window.pica({ features: ["all"] });
      pica
        .resize(img, canvas)
        .then((result) => pica.toBlob(result, "image/jpeg", 0.9))
        .then((blob) => {
          const blob_obj = new Blob([blob], {
            type: "image/jpeg",
          });
          const link = document.createElement("a");
          link.href = window.URL.createObjectURL(blob_obj);
          link.download = file_name + ".jpg";
          link.click();
          window.URL.revokeObjectURL(link.href);
        });
    };
  }

  resizeImage("./images/1.jpg", "download");
</script>

批量压缩文件域选择的图片并打包下载

<script src="./plugins/pica.min.js"></script>
<script src="./plugins/jszip.min.js"></script>
<script src="./plugins/FileSaver.js"></script>
<input type="file" id="files" multiple onchange="previewImages(this)" accept="image/*" />
<div id="con-obj" class="container"></div>
<div id="con-data" class="container"></div>
<div id="con-resize" class="container"></div>
<script>
  function previewImages(this_obj) {
    const elem_con_obj = document.querySelector("#con-obj");
    const elem_con_data = document.querySelector("#con-data");
    const elem_con_resize = document.querySelector("#con-resize");

    const file_list = [];
    for (let i in this_obj.files) {
      const file = this_obj.files[i];
      if (["image/jpeg", "image/png"].indexOf(file.type) < 0) continue;
      file_list.push(file);
    }

    Promise.all(
      file_list.map((file) => {
        return new Promise((resolve, reject) => {
          //预览
          const elem_img = document.createElement("img");
          elem_img.src = window.URL.createObjectURL(file);
          elem_con_obj.append(elem_img);
          console.log(elem_img.src);//blob:http://localhost:3000/80e8fa2c-caa1-4a23-a6d2-01bdac2843e2

          const file_reader = new FileReader();
          file_reader.readAsDataURL(file);
          file_reader.onload = (e) => {
            const img = new Image();
            img.src = e.target.result;
            img.onload = function () {
              //预览
              elem_con_data.append(img);
              console.log(img.src);//data:image/png;base64,iVBORw0...

              const canvas = document.createElement("canvas");
              canvas.width = img.width;
              canvas.height = img.height;

              //压缩
              const pica = window.pica({ features: ["all"] });
              pica
                .resize(img, canvas)
                .then((result) => pica.toBlob(result, "image/jpeg", 0.9))
                .then((blob) => {
                  resolve({ blob: blob, file_name: file.name });

                  //预览
                  const elem_img_resize = document.createElement("img");
                  elem_img_resize.src = window.URL.createObjectURL(blob);
                  elem_con_resize.append(elem_img_resize);
                  console.log(elem_img_resize.src);//blob:http://localhost:3000/d2868663-aef0-48a2-8bdc-5e6d9f168a2e
                });
            };
            img.onerror = function () {
              reject("not a image");
            };
          };
          file_reader.onerror = function () {
            reject("read error");
          };
        });
      })
    )
      .then((images) => {
        console.log(images);
        const zip = new JSZip();
        for (let i in images) {
          zip.file(images[i]["file_name"], images[i]["blob"]);
        }
        zip.generateAsync({ type: "blob" }).then((blob) => {
          saveAs(blob, "compress.zip");
        });
      })
      .catch((err) => {
        console.error("Error packaging images:", err);
      });
  }
</script>

 以上方法由于使用了Promise.all 保证了所有图片压缩完成后进行打包下载,然而由于Promise.all的特性,若图片中出现伪装成图片的文件会导致当前Promise走向reject,进一步导致了Promise.all 的失败。

尝试解决这个问题,使用Promise.allSettled 改写上面的代码。

<script>
  function previewImages(this_obj) {
    const elem_con_obj = document.querySelector("#con-obj");
    const elem_con_data = document.querySelector("#con-data");
    const elem_con_resize = document.querySelector("#con-resize");

    const file_list = [];
    for (let i in this_obj.files) {
      const file = this_obj.files[i];
      if (["image/jpeg", "image/png"].indexOf(file.type) < 0) continue;
      file_list.push(file);
    }

    Promise.allSettled(
      file_list.map((file) => {
        return new Promise((resolve, reject) => {
          //预览
          const elem_img = document.createElement("img");
          elem_img.src = window.URL.createObjectURL(file);
          elem_con_obj.append(elem_img);

          const file_reader = new FileReader();
          file_reader.readAsDataURL(file);
          file_reader.onload = (e) => {
            const img = new Image();
            img.src = e.target.result;
            img.onload = function () {
              //预览
              elem_con_data.append(img);

              const canvas = document.createElement("canvas");
              canvas.width = img.width;
              canvas.height = img.height;

              //压缩
              const pica = window.pica({ features: ["all"] });
              pica
                .resize(img, canvas)
                .then((result) => pica.toBlob(result, "image/jpeg", 0.9))
                .then((blob) => {
                  resolve({ blob: blob, file_name: file.name });

                  //预览
                  const elem_img_resize = document.createElement("img");
                  elem_img_resize.src = window.URL.createObjectURL(blob);
                  elem_con_resize.append(elem_img_resize);
                });
            };
            img.onerror = function () {
              reject("not a image");
            };
          };
          file_reader.onerror = function () {
            reject("read error");
          };
        });
      })
    )
      .then((images) => {
        console.log(images);
        const zip = new JSZip();
        for (let i in images) {
          if (images[i]["status"] == "rejected") continue;

          const image = images[i]["value"];
          zip.file(image["file_name"], image["blob"]);
        }
        zip.generateAsync({ type: "blob" }).then((blob) => {
          saveAs(blob, "compress.zip");
        });
      })
      .catch((err) => {
        console.error("Error packaging images:", err);
      });
  }

    
</script>

即可保证所有真正的图片可以正常压缩和打包下载。 

标签:const,img,前端,elem,js,blob,file,pica,con
From: https://www.cnblogs.com/caroline2016/p/18359242

相关文章

  • 文心快码 Baidu Comate 前端工程师观点分享:行业现状(一)
    本系列视频来自百度工程效能部的前端研发经理杨经纬,她在由开源中国主办的“AI编程革新研发效能”OSC源创会·杭州站·105期线下沙龙活动上,从一款文心快码(BaiduComate)前端工程师的角度,分享了关于智能研发工具本身的研发历程和理念。​​​​​​​本视频是关于【AI编程行业......
  • JAVA毕业设计|ssm高校宿舍管理系统的设计与开发jsp包含文档代码讲解
    收藏点赞不迷路 关注作者有好处文末获取源码一、系统展示二、万字文档展示 基于ssm高校宿舍管理系统的设计与开发jsp开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis+Vue工具:IDEA/Ecilpse、Navicat、Maven 编号:ssm283一、系统展示二、万字文档展示第......
  • 文心快码 Baidu Comate 前端工程师观点分享:行业现状(二)
    本系列视频来自百度工程效能部的前端研发经理杨经纬,她在由开源中国主办的“AI编程革新研发效能”OSC源创会·杭州站·105期线下沙龙活动上,从一款文心快码(BaiduComate)前端工程师的角度,分享了关于智能研发工具本身的研发历程和理念。以下视频是关于【AI编程行业现状】的观点2。......
  • JAVA毕业设计|(免费)基于SSM的蛋糕甜品店管理系统的设计与开发jsp包含文档代码讲解
    收藏点赞不迷路 关注作者有好处编号:ssm544基于SSM的蛋糕甜品店管理系统的设计与开发jsp开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis+Vue工具:IDEA/Ecilpse、Navicat、Maven文末获取源码(免费|领源码)1.系统展示2.万字文档展示第5章系统详细设计5.1个人中......
  • 毕业设计|基于SSM的蛋糕甜品店管理系统的设计与开发jsp|免费|代码讲解
    收藏点赞不迷路 关注作者有好处编号:ssm544基于SSM的蛋糕甜品店管理系统的设计与开发jsp开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis+Vue工具:IDEA/Ecilpse、Navicat、Maven文末获取源码(免费|领源码)1.系统展示2.万字文档展示第5章系统详细设计5.1个人中......
  • 毕业设计|ssm基于java web的商铺租赁管理系统的jsp|免费|代码讲解
    收藏点赞不迷路 关注作者有好处编号:ssm405ssm基于javaweb的商铺租赁管理系统的jsp开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis+Vue工具:IDEA/Ecilpse、Navicat、Maven文末获取源码(免费领源码)1.系统展示2.万字文档展示第5章系统详细设计这个环节需要使......
  • gdb 查看 jsoncpp对象
    jsoncpp是c++使用较多的json库,gdb调试时,不方便查看json对象的信息,这里提供一种方法。json::value利用map实现树状对象,map的类型为std::maps<Json::Value::CZString, Json::Value>unionValueHolder{LargestIntint_;LargestUIntuint_;doublereal_;boolbo......
  • 前端可视化大屏适配方案
    最开始比较流行的三大解决方式:rem方案动态设置 HTML 根字体大小和 body 字体大小,配合百分比或者 vw/vh 实现容器宽高、字体大小、位移的动态调整vw/vh方案将像素值(px)按比例换算为视口宽度(vw)和视口高度(vh),能够实时计算图表尺寸、字体大小等scale方案根据宽高......
  • 基于 canal+mysql 实现 yjs-schema 数据实时同步
    MySQL自动同步开源工具在现代的数据处理中,数据同步是非常重要的一个环节。MySQL作为一个广泛应用的数据库管理系统,自动同步数据也是一个比较常见的需求。今天我们将介绍一些开源工具,可以帮助我们实现MySQL数据库的自动同步。1.MaxScaleMaxScale是一个开源的MySQLProxy工具,它......
  • 前端会话管理
    1.1会话管理概述1.1.1为什么需要会话管理会话管理(SessionManagement)是Web开发中的一项关键技术,用于在用户与服务器之间的多次交互中维持状态。HTTP协议本质上是无状态的,这意味着每次请求都是独立的,服务器不会记住之前的请求。因此,会话管理被引入以在用户与服务器之......