CSDN博客文章缩略图生成器
起因:
- 之前注意到CSDN可以随机选取文章缩略图,但后来这个功能似乎取消了。于是我想调整一下缩略图的配色方案。
html制作界面
界面分上下两块区域,上面是参数配置,下面是效果预览图。
-
参数配置:
- 文本内容自定义:输入关键词生成图片中间的文本内容(建议简短);
- 背景色调整:提供预设颜色选项和通过颜色选择器选择颜色;
- 图片尺寸:默认宽480像素,高270像素
-
功能说明:
- 由选择颜色或随机生成颜色生成图片,如果不满意还可以预设颜色,之后可以把图片保存下来,通过重置参数就可以达到随机生成的效果;
- 由选择颜色或随机生成颜色生成图片,如果不满意还可以预设颜色,之后可以把图片保存下来,通过重置参数就可以达到随机生成的效果;
生成效果
- 生成的效果图
代码部分
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>CSDN博客文章缩略图生成器</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
.container {
text-align: center;
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
.form-group {
margin-bottom: 10px;
}
.form-group label {
display: inline-block;
width: 100px;
text-align: right;
margin-right: 10px;
}
.form-group input[type="text"],
.form-group input[type="number"]{
padding: 5px;
width: 200px;
margin-left: 10px;
}
.form-group input[type="color"] {
padding: 0;
width: 210px;
margin-left: 12px;
border: none;
cursor: pointer;
}
.form-group select {
padding: 5px;
width: 213px;
margin-left: 10px;
border-radius: 4px;
border: 1px solid #ccc;
}
.form-group select:disabled {
background-color: #eee;
cursor: not-allowed;
}
.form-group select:hover {
border-color: #888;
}
.controls {
display: flex;
justify-content: center;
margin-top: 20px;
align-items: center;
flex-wrap: nowrap;
margin-top: 20px;
gap: 20px;
}
.controls button {
margin-top: 10px;
padding: 8px 16px;
cursor: pointer;
}
#preview {
margin-top: 20px;
border-radius: 10px;
overflow: hidden;
}
canvas {
width: 100%;
height: auto;
margin-top: 20px;
border-radius: 10px;
}
</style>
</head>
<body>
<div class="container">
<h2>CSDN博客文章缩略图生成器</h2>
<!-- 配置选项 -->
<div class="form-group">
<label for="text">文本内容:</label>
<input type="text" id="text" placeholder="请输入文本内容" value="#示例文本"/>
</div>
<div class="form-group">
<label for="presetColors">颜色预设:</label>
<select id="presetColors" onchange="applyPresetColor()">
<option value="" selected>请选择</option>
<option value="#FE5F20">Java专栏色</option>
<option value="#5E61CB">学车专栏色</option>
<option value="#3A80A8">数据库专栏色</option>
<option value="#34B3BC">其他专栏色</option>
<option value="#90839B">(其他)Linux文章色</option>
<option value="#34B3BC">(其他)软件文章色</option>
</select>
</div>
<div class="form-group">
<label for="bgColor">背景颜色:</label>
<input type="color" id="bgColor" value="#ffffff">
</div>
<div class="form-group">
<label for="width">宽度:</label>
<input type="number" id="width" value="480"/>
</div>
<div class="form-group">
<label for="height">高度:</label>
<input type="number" id="height" value="270"/>
</div>
<div class="controls">
<button onclick="generateImage()">生成图片</button>
<button onclick="downloadImage()">保存图片</button>
<button onclick="resetColor()">重置参数</button>
</div>
<!-- 预览区域 -->
<div id="preview">
<canvas id="myCanvas"></canvas>
</div>
</div>
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
// 颜色值校验
function isValidHexColor(color) {
const regex = /^#([0-9A-Fa-f]{6})$/;
return regex.test(color);
}
// 颜色随机
function getRandomColor() {
return '#' + Math.floor(Math.random()*16777215).toString(16);
}
// 重置颜色参数
function resetColor() {
document.getElementById("presetColors").value = ""; // 清空下拉框选择
document.getElementById("bgColor").value = "#ffffff"; // 重置颜色选择器为默认白色
userSelectedColor = false; // 允许 generateImage 使用随机色
generateImage(); // 重新生成图片
}
// 生成渐变色
function generateGradient(startColor, endColor, width, height) {
let gradient = ctx.createLinearGradient(0, 0, width, height);
//gradient.addColorStop(0, startColor);
gradient.addColorStop(0.5, adjustBrightness(startColor, -0.1));
gradient.addColorStop(1, endColor);
return gradient;
}
// 图形生成
let userSelectedColor = false;
function generateImage() {
const text = document.getElementById("text").value || "#示例文本内容";
const bgColorInput = document.getElementById("bgColor").value;
const width = parseInt(document.getElementById("width").value) || 480;
const height = parseInt(document.getElementById("height").value) || 270;
// 设置画布尺寸
canvas.width = width;
canvas.height = height;
// 清除画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 判断是否用户选择了颜色
let bgColor;
if (userSelectedColor || bgColorInput !== "#ffffff") {
bgColor = isValidHexColor(bgColorInput) ? bgColorInput : getRandomColor();
} else {
bgColor = getRandomColor();
}
// 创建渐变背景
ctx.fillStyle = generateGradient(bgColor, adjustBrightness(bgColor, -0.2), width, height);
ctx.fillRect(0, 0, width, height);
// 绘制多个斜坡形状
ctx.beginPath();
ctx.moveTo(1, height); // A点,左下角
ctx.lineTo(width * 0.9, height); // B点,右下角
ctx.lineTo(0, height * 0.196); // C点,右上角
ctx.closePath();
ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
ctx.fill();
ctx.beginPath();
ctx.moveTo(1, height); // A点,左下角
ctx.lineTo(width * 0.45, height); // B点,右下角
ctx.lineTo(0, -230); // C点,左上角
ctx.closePath();
ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
ctx.fill();
// 绘制多个半球形状
ctx.beginPath();
ctx.arc(width * 0.95, height * 0.1, Math.min(width, height) * 0.2, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
ctx.fill();
ctx.beginPath();
ctx.arc(width * 0.1, height * 0.75, Math.min(width, height) * 0.2, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
ctx.fill();
// 设置字体样式
//ctx.font = `bold ${Math.min(width / text.length, 60)}px Arial`; // 根据画布宽度调整字体大小
ctx.font = "bold 60px Arial"
ctx.textAlign = "center";
ctx.fillStyle = "#ffffff";
// 计算文字位置以确保居中显示
const metrics = ctx.measureText(text);
const x = canvas.width / 2;
const y = (canvas.height / 2) + (metrics.actualBoundingBoxAscent / 2);
// 绘制文本
ctx.fillText(text, x, y);
}
// 调整图片亮度
function adjustBrightness(hex, correctionFactor) {
if (!/^#([0-9A-Fa-f]{6})$/.test(hex)) {
console.warn("Invalid color format:", hex);
return "#000000"; // fallback
}
hex = hex.replace(/^#/, '');
let r = parseInt(hex.substr(0, 2), 16),
g = parseInt(hex.substr(2, 2), 16),
b = parseInt(hex.substr(4, 2), 16);
// 调整亮度,使用线性方式更直观
r = Math.max(0, Math.min(255, Math.round(r + 255 * correctionFactor)));
g = Math.max(0, Math.min(255, Math.round(g + 255 * correctionFactor)));
b = Math.max(0, Math.min(255, Math.round(b + 255 * correctionFactor)));
// 确保返回为 6 位颜色
const toHex = (c) => c.toString(16).padStart(2, '0');
return "#" + toHex(r) + toHex(g) + toHex(b);
}
// 下载图片
function downloadImage() {
const link = document.createElement('a');
link.download = 'generated-image.png';
link.href = canvas.toDataURL('image/png');
link.click();
}
// 预设颜色应用
function applyPresetColor() {
const colorPicker = document.getElementById('bgColor');
if (colorPicker) { // 检查是否成功获取到元素
const presetColor = document.getElementById('presetColors').value;
colorPicker.value = presetColor;
generateImage(); // 更新图片预览
} else {
console.error("未能找到ID为'bgColor'的元素");
}
}
// 添加事件监听器来检测颜色选择
document.getElementById('bgColor').addEventListener('input', () => {
userSelectedColor = true;
generateImage();
});
// 页面加载时默认生成一张图片
window.onload = () => generateImage();
</script>
</body>
</html>