123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>webp</title>
- <style>
- #image-display, #image-display2, #image-display3 {
- max-width: 45%;
- max-height: 45%;
- border: 1px solid gray;
- }
- </style>
- <script src="js/conversion.js"></script>
- </head>
- <body>
- <h1>粘贴图片并展示</h1>
- <p>右键粘贴图片,本地图片或网络图片地址都可以,将被压缩为webp格式并展示,压缩前:<span id="preSize"></span>, 压缩后:<span id="afterSize"></span><span id="status"></span> 。
- <button onclick="rotateImage()">旋转90度</button> 。
- <!-- <button onclick="bigImage()">放大</button> 。 -->
- <!-- <button onclick="smallImage()">缩小</button> 。 -->
- </p>
- <div id="image-container">
- <div>base64 webp</div>
- <img id="image-display" src="" alt="Image Display">
- <div>本地 png < 300k</div>
- <img id="image-display3" src="" alt="Image Display">
- </div>
- <script>
- const imageDisplay = document.getElementById("image-display");
- function formatSize(sizeInBytes) {
- const sizeInKb = sizeInBytes / 1024;
- const sizeInMb = sizeInBytes / 1048576;
- if (sizeInMb >= 1) {
- return `${sizeInMb.toFixed(2)} MB`;
- } else {
- return `${sizeInKb.toFixed(2)} KB`;
- }
- }
- // 监听粘贴事件
- document.addEventListener("paste", (event) => {
- handleClipboardItems(event.clipboardData.items);
- });
- // 监听拖拽事件
- document.addEventListener("dragover", (event) => {
- event.preventDefault();
- });
- document.addEventListener("drop", (event) => {
- event.preventDefault();
- handleClipboardItems(event.dataTransfer.items);
- });
- function compressImageToSize(blobFile, targetSize = 300 * 1024, maxIterations = 5, minQuality = 0.01) {
- let currentQuality = 0.8; // 初始压缩质量
- let iteration = 0; // 当前迭代次数
- function compressImage(blobFile, quality = 0.8) {
- // 返回一个Promise对象
- return new Promise((resolve, reject) => {
- // 创建一个Image对象
- const image = new Image();
- // 当Image对象加载完成时,执行以下操作
- image.onload = () => {
- const canvas = document.createElement("canvas");
- canvas.width = image.naturalWidth;
- canvas.height = image.naturalHeight;
- const context = canvas.getContext("2d");
- context.drawImage(image, 0, 0);
- canvas.toBlob((webpBlob) => {
- // 解决Promise,并传递压缩后的Blob对象
- resolve(webpBlob);
- }, "image/webp", quality);
- // 如果在转换过程中发生错误,拒绝Promise
- };
- image.src = URL.createObjectURL(blobFile);
- });
- }
- function attemptCompression() {
- return new Promise((resolve, reject) => {
- // 递归调用compressImage函数进行压缩
- compressImage(blobFile, currentQuality).then(compressedBlob => {
- // 检查压缩后的文件大小是否满足条件
- if (compressedBlob.size <= targetSize) {
- // 如果压缩后的文件大小小于或等于目标大小,则解决Promise
- resolve(compressedBlob);
- } else if (iteration < maxIterations && currentQuality > minQuality) {
- // 如果还未达到最大迭代次数且质量还可以降低,则递减质量并再次尝试压缩
- currentQuality *= 0.8; // 每次迭代降低质量的百分比
- blobFile = compressedBlob; // 使用上一次压缩的结果作为下一次的输入
- iteration++; // 增加迭代次数
- attemptCompression().then(resolve).catch(reject);
- } else {
- // 如果已经达到最大迭代次数或者质量已经很低,拒绝Promise
- reject(new Error("Unable to compress the image to the target size."));
- }
- }).catch(reject);
- });
- }
- // 启动压缩过程
- return new Promise((resolve, reject) => {
- attemptCompression().then(resolve).catch(reject);
- });
- }
- // 处理粘贴板或拖拽项
- function handleClipboardItems(items) {
- if (!items) {
- return;
- }
- // 查找图片数据
- for (let i = 0; i < items.length; i++) {
- if (items[i].type.indexOf("image") !== -1) {
- document.getElementById("preSize").innerText = "";
- document.getElementById("afterSize").innerText = "";
- // 获取图片文件或URL
- const blobFile = items[i].getAsFile();
- // 将图片展示
- document.getElementById("status").innerText = " 压缩中……";
- document.getElementById("preSize").innerText = formatSize(blobFile.size);
- // 压缩为webp格式
- compressImageToSize(blobFile).then(webpBlob => {
- // 将压缩后的webp图片展示在页面上
- // imageDisplay.src = URL.createObjectURL(webpBlob);
- const reader = new FileReader();
- reader.onloadend = () => {
- imageDisplay.src = reader.result;
- // toWebP();
- toPng();
- };
- reader.readAsDataURL(webpBlob);
- showSize(webpBlob);
- });
- // 防止页面跳转
- event.preventDefault();
- break
- }
- }
- }
- function showSize(webpBlob) {
- document.getElementById("status").innerText = " 已压缩 ☺";
- document.getElementById("afterSize").innerText = formatSize(webpBlob.size);
- }
- // 选择90度旋转
- function rotateImage() {
- const image = document.getElementById("image-display");
- const canvas = document.createElement("canvas");
- const context = canvas.getContext("2d");
- // 旋转90度
- canvas.width = image.height;
- canvas.height = image.width;
- context.rotate(90 * Math.PI / 180);
- context.drawImage(image, 0, -canvas.width);
- // 将旋转后的图片展示在页面上
- const rotatedImageUrl = canvas.toDataURL();
- image.src = rotatedImageUrl;
- }
- function base64ToPng(base64Data, callBack) {
- // 创建一个新的 Image 对象
- const img = new Image();
- // 当图像加载完成时执行转换逻辑
- img.onload = function () {
- // 创建一个新的 Canvas 元素
- const canvas = document.createElement('canvas');
- const ctx = canvas.getContext('2d');
- // 设置 Canvas 的尺寸与图像一样
- canvas.width = img.width;
- canvas.height = img.height;
- // 将 base64 图像绘制到 Canvas 上
- ctx.drawImage(img, 0, 0);
- // 将 Canvas 转换为 PNG 格式的 Blob 对象
- canvas.toBlob(function (blob) {
- // 将 Blob 对象传递给其他地方使用,比如保存到本地或上传到服务器
- // 这里我们简单地打印 Blob 对象的大小和类型
- console.log("生成的 PNG Blob 大小:", blob.size, "类型:", blob.type);
- callBack(blob);
- }, 'image/png');
- };
- // 设置图像的 src 为 base64 数据
- img.src = base64Data;
- }
- function toPng() {
- // 将base64图片转为本地路径
- const image = document.getElementById("image-display");
- base64ToPng(image.src, function (blob) {
- imageConversion.compressAccurately(blob, 300).then(res => {
- console.log(res);
- document.getElementById("image-display3").src = URL.createObjectURL(res);
- })
- })
- }
- </script>
- </body>
- </html>
|