图片格式转化之 webp 转为 png

WebP 是现代图像格式中的"通用选手",在多数情况下比 PNG、JPEG、GIF 都更节省空间,同时功能更全面。但是某些网站只支持上传 png 或者 jpg,所以要将 webp 转为 png。

1.base64ToBlob 中要转为 8位字节

base64ToBlob 中要转为 8位字节是为了还原出原始的二进制文件数据(字节流),因为只有 JS 字符串的每个字符是 16 位(UTF-16),而一组真实的 8 位字节流 才能被浏览器或文件系统识别成 图片、音频、视频、压缩包等二进制文件。 Base64 解码后的字符都是 0~255 的字节(低8位有效,高8位都是0),可以用 charCodeAt 去获取 真实8位字节值

2.Base64 => blob => 下载

维度 直接 Base64 Data URL Base64 → Blob → 下载
内存使用 高,Base64 是冗长的字符串,占用较大内存。base64 编码的体积比原始二进制大 约 33% 【原因:每 3 个字节(24 bit)编码成 4 个字符(每个字符 6 bit)】 低,Blob 直接存储二进制,内存开销更小
文件大小限制 受限,浏览器对 URL 长度有限制 Blob URL 本质上不是存放文件内容的"字符串",而是浏览器内部为那个二进制数据对象创建的一个"指针"或"句柄"。它只是一个很短的标识符,指向浏览器内存(或者磁盘)中的真实文件数据,所以它不受 URL 长度限制
兼容性 较差,部分老旧浏览器和环境支持不佳 较好,主流浏览器和环境均支持
控制粒度 低,只能用于简单下载 高,支持内存释放、分片、上传、文件操作等功能
安全性 低,Base64 数据直接暴露在 URL 中,有一定XSS风险 高,Blob URL 是临时生成,外部无法直接访问内容
js 复制代码
<div class="input-area">  
    <input type="file" id="webp-input" accept=".webp" onchange="javascript:preview()" />
    <div id="img-preview">
        
    </div>
    <button onclick="convertWebp('image/png')">转换成png</button>
    <button onclick="convertWebp('image/jpg')">转换成jpg</button>
</div>  
  
<div class="output-area" id="output-area">  
    <!-- 下载链接将在这里动态生成 -->  
</div>  
  
<script>  
function preview(){
    const imgContent = document.getElementById('img-preview');
    const file = document.getElementById("webp-input").files[0];
    imgContent.innerHTML = '';
    const img = document.createElement('img');
    img.src = URL.createObjectURL(file);	// 将上传的文件对象转为临时URL(blob URL)
    imgContent.appendChild(img);
    img.onload = function() {
        URL.revokeObjectURL(this.src);	// 图片加载完成后,释放上面创建的临时URL占用的内存资源
    }
}
function base64ToBlob(base64, mimeType) {
    const byteString = atob(base64.split(',')[1]);	// 拿到base6内容部分,将其解码为字符串
    const ab = new ArrayBuffer(byteString.length);	// 创建ArrayBuffer
    const ia = new Uint8Array(ab);	// 创建字节数组视图,可以像数组一样操作每个字节
    for (let i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);	// 转换每个字符为字节
    }
    return new Blob([ab], { type: mimeType });
}
function downloadBlob(blob, filename) {
    const url = URL.createObjectURL(blob);		// 生成 blob URL
    const link = document.createElement('a');
    link.href = url;
    link.download = filename;			
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
}
function convertWebp(mimeType) {  
    const inputElement = document.getElementById('webp-input');  
    const file = inputElement.files[0];  
    if (!file) {  
        alert('Please select a WebP file first.');  
        return;  
    }  
    const reader = new FileReader();  
    reader.onload = function(event) {  
        const img = new Image();  
        img.onload = function() {  
            const canvas = document.createElement('canvas');  
            canvas.width = img.width;  
            canvas.height = img.height;  
            const ctx = canvas.getContext('2d');  // 获取canvas的2D渲染上下文对象ctx,用于绘图
            ctx.drawImage(img, 0, 0, img.width, img.height);  	// 将图片绘制到canvas上(从左上角开始,宽高与图片一致)
            const base64 = canvas.toDataURL(mimeType); // 将canvas按指定格式导出成base64数据URL,如:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...
            const blob = base64ToBlob(base64, mimeType);
            const filename = mimeType === 'image/png' ? 'converted.png' : 'converted.jpg';
            downloadBlob(blob, filename);
        };  
        img.src = event.target.result;  
    };  
    reader.readAsDataURL(file);  
}  
</script>  
相关推荐
自律懒人3 小时前
ChatGPT Work 上线当天实测:GPT-5.6 Sol 把 Codex 塞进桌面应用,跨应用自动做报表和 PPT,一个指令干 3 小时的活
javascript·开源
CappuccinoRose3 小时前
CSS、Less、Sass(含 SCSS)、Stylus
前端·css·less·sass·stylus
不听话坏12 小时前
Ignition篇(下 一) 动态执行前的事情
开发语言·前端·javascript
likeyi0712 小时前
require 和 import的区别
开发语言·前端
pany12 小时前
做 AI 友好的开源 Vue3 模板 🌈
前端·vue.js·ai编程
小二·13 小时前
React 19 + Next.js 15 现代前端开发实战:App Router / Server Components / 流式渲染
前端·javascript·react.js
谙忆102414 小时前
前端图片直传对象存储:OSS/S3 预签名 URL、STS 临时凭证与回调校验
前端
CHNE_TAO_EMSM15 小时前
Android studio 打开文件时自动下载源码
前端·javascript·android studio
一孤程16 小时前
Airtest自动化测试第五篇:小程序与Web测试——跨平台自动化全覆盖
前端·自动化测试·小程序·自动化·测试·airtest
IT_陈寒16 小时前
SpringBoot自动配置不是你以为的那样的智能
前端·人工智能·后端