base64图片压缩工具代码
有的时候图片需要压缩,但是有些很苛刻的条件下图片不能直接放直链的时候,可以把图片转换为base64字符串,但是如何图片很大的话这个base64字符串是会更长的,如何对图片型base64的字符串进行如何再次压缩呢?找到了资料和这个代码,利用重画的原理,也就是同样也是压缩图片的原理,亲测有效,在某些时候对画质要求不高,但是对字符串长度、字节大小有要求的时候,这个工具的作用就体现出来了
参考资料:https://blog.csdn.net/weixin_42752574/article/details/126061352
控制台调试版代码(原版)
原参考资料丢进html里,在src里替换你需要压缩的图片base64,最后再浏览器访问网页,打开F12开发者工具,控制台就能看到console.log输出的压缩后的代码了
<meta charset="UTF-8">
<script>
let targetObj = {
// 图片base64放置
src: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAA'}
function compressImg (base64, multiple, useImg, targetObj) {
// 第一个参数就是需要加密的base65,
// 第二个是压缩系数 0-1,
// 第三个压缩后的回调 用来获取处理后的 base64
if (!base64) {
return
}
// const _this = this
const length = base64.length / 1024
// 压缩方法
let newImage = new Image()
let quality = 1 // 压缩系数0-1之间
newImage.src = base64
newImage.setAttribute('crossOrigin', 'Anonymous') // url为外域时需要
let imgWidth,
imgHeight
let w = undefined
newImage.onload = function () {
// 这里面的 this 指向 newImage
// 通过改变图片宽高来实现压缩
w = this.width * multiple
imgWidth = this.width
imgHeight = this.height
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')
if (Math.max(imgWidth, imgHeight) > w) {
if (imgWidth > imgHeight) {
canvas.width = w
// 等比例缩小
canvas.height = w * (imgHeight / imgWidth)
} else {
canvas.height = w
// 等比例缩小
canvas.width = w * (imgWidth / imgHeight)
}
} else {
canvas.width = imgWidth
canvas.height = imgHeight
// quality 设置转换为base64编码后图片的质量,取值范围为0-1 没什么压缩效果
// 还是得通过设置 canvas 的宽高来压缩
quality = 0.6
}
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(this, 0, 0, canvas.width, canvas.height) // // 这里面的 this 指向 newImage
let smallBase64 = canvas.toDataURL('image/jpeg', quality) // 压缩语句
// 如想确保图片压缩到自己想要的尺寸,如要求在50-150kb之间,请加以下语句,quality初始值根据情况自定
// while (smallBase64.length / 1024 > 150) {
// quality -= 0.01;
// smallBase64 = canvas.toDataURL("image/jpeg", quality);
// }
// 防止最后一次压缩低于最低尺寸,只要quality递减合理,无需考虑
// while (smallBase64.length / 1024 < 50) {
// quality += 0.001;
// smallBase64 = canvas.toDataURL("image/jpeg", quality);
// }
// 必须通过回调函数返回,否则无法及时拿到该值,回调函数异步执行
console.log(`压缩前:${length}KB`)
console.log(`压缩后:${smallBase64.length / 1024} KB`)
useImg(smallBase64, targetObj)
}
}
function useImg (base64, targetObj) {
// targetObj 通过值引用的特性 用处理后的 base64 覆盖 处理前的 base63
console.log('压缩后的 base64 :', base64)
targetObj.src = base64
}
compressImg(targetObj.src, 0.9, useImg, targetObj)
</script>
改进版代码--可视化
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Base64 图像压缩工具</title>
<style>
body {
font-family: 'Arial', sans-serif;
background-color: #f8f9fa;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
background: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 600px;
}
h1 {
text-align: center;
color: #333;
}
.input-group {
margin-bottom: 15px;
}
.input-group label {
display: block;
margin-bottom: 8px;
font-size: 14px;
color: #555;
}
.input-group input, .input-group textarea {
width: 100%;
padding: 10px;
font-size: 14px;
border: 1px solid #ccc;
border-radius: 4px;
background-color: #f9f9f9;
}
.input-group input[type="number"] {
width: 50%;
}
.output-group {
text-align: center;
}
.output-group img {
max-width: 100%;
border: 1px solid #ddd;
border-radius: 8px;
margin: 20px 0;
}
.btn {
display: inline-block;
padding: 10px 20px;
background-color: #007bff;
color: white;
font-size: 16px;
text-align: center;
border-radius: 4px;
cursor: pointer;
border: none;
transition: background-color 0.3s;
}
.btn:hover {
background-color: #0056b3;
}
.result {
margin-top: 20px;
font-size: 14px;
color: #555;
}
#compressedBase64Input {
display: none;
}
</style>
</head>
<body>
<div class="container">
<h1>Base64 图像压缩工具</h1>
<div class="input-group">
<label for="base64Input">输入 Base64 编码:</label>
<textarea id="base64Input" rows="6" placeholder="粘贴 Base64 编码到这里"></textarea>
</div>
<div class="input-group">
<label for="qualityInput">压缩系数 (0 - 1):</label>
<input type="number" id="qualityInput" value="0.9" min="0" max="1" step="0.01">
</div>
<div class="input-group">
<button class="btn" onclick="compressAndDisplay()">压缩并显示</button>
</div>
<div class="output-group">
<img id="outputImg" alt="压缩后图像" style="display: none;">
<div class="result">
<p id="sizeBefore">压缩前:-- KB</p>
<p id="sizeAfter">压缩后:-- KB</p>
</div>
</div>
<!-- 压缩后 Base64 的输入框 -->
<div class="input-group" id="compressedBase64Input">
<label for="compressedBase64">压缩后的 Base64 编码:</label>
<textarea id="compressedBase64" rows="6" readonly></textarea>
</div>
</div>
<script>
function compressAndDisplay() {
const base64Input = document.getElementById('base64Input').value;
const qualityInput = parseFloat(document.getElementById('qualityInput').value);
const outputImg = document.getElementById('outputImg');
const sizeBefore = document.getElementById('sizeBefore');
const sizeAfter = document.getElementById('sizeAfter');
const compressedBase64Input = document.getElementById('compressedBase64Input');
const compressedBase64TextArea = document.getElementById('compressedBase64');
// 防止空输入
if (!base64Input || !base64Input.startsWith("data:image/")) {
alert("请输入有效的 Base64 编码!");
return;
}
// 创建一个图像对象
const img = new Image();
img.src = base64Input;
img.onload = function() {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// 设定压缩比例
const width = img.width * qualityInput;
const height = img.height * qualityInput;
canvas.width = width;
canvas.height = height;
ctx.clearRect(0, 0, width, height);
ctx.drawImage(img, 0, 0, width, height);
// 转换为 Base64 并计算文件大小
const compressedBase64 = canvas.toDataURL('image/jpeg', qualityInput);
const originalSize = (base64Input.length / 1024).toFixed(2);
const compressedSize = (compressedBase64.length / 1024).toFixed(2);
// 更新界面内容
sizeBefore.textContent = `压缩前:${originalSize} KB`;
sizeAfter.textContent = `压缩后:${compressedSize} KB`;
outputImg.src = compressedBase64;
outputImg.style.display = 'block'; // 显示图像
// 显示压缩后的 Base64 编码
compressedBase64TextArea.value = compressedBase64;
compressedBase64Input.style.display = 'block'; // 显示压缩后的 Base64 输入框
};
}
</script>
</body>
</html>