xw-devtool-cli 1.0.8 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/package.json +1 -1
- package/src/commands/placeholderImg.js +88 -0
- package/src/index.js +6 -1
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
- **图片工具**:
|
|
11
11
|
- **图片格式转换**:支持 PNG、JPG、WebP 格式互转,可调整压缩质量。
|
|
12
12
|
- **图片 ↔ Base64**:支持图片转 Base64 字符串,以及 Base64 还原为图片文件。
|
|
13
|
+
- **占位图生成**:快速生成指定尺寸、颜色、文字的占位图片 (Placeholder Image)。
|
|
13
14
|
- **Mock 数据生成**:
|
|
14
15
|
- 支持生成:英文段落 (Lorem Ipsum)、中文字符、中国居民身份证号、电子邮箱、URL、订单号、手机号、座机号。
|
|
15
16
|
- 支持批量生成。
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
- **特殊符号大全**:包含常用符号、箭头、数学符号、货币、希腊字母等 170+ 个符号,支持一键复制。
|
|
28
29
|
- **Emoji 输入**:支持分类查看和选择常用 Emoji,一键复制到剪贴板。
|
|
29
30
|
- **HTML 实体工具**:支持 HTML 实体编码与解码 (如 `&` <-> `&`)。
|
|
31
|
+
- **占位图生成**:自定义尺寸、背景色、文字颜色和格式生成占位图。
|
|
30
32
|
- **便捷操作**:
|
|
31
33
|
- 支持文件选择对话框 (Windows)。
|
|
32
34
|
- 结果自动复制到剪贴板。
|
|
@@ -74,6 +76,7 @@ c. QR Code Generator
|
|
|
74
76
|
d. Special Characters (Symbols)
|
|
75
77
|
e. Emoji Picker
|
|
76
78
|
f. HTML Entity Encode/Decode
|
|
79
|
+
g. Placeholder Image Generator
|
|
77
80
|
0. Exit
|
|
78
81
|
=================================
|
|
79
82
|
```
|
|
@@ -168,6 +171,15 @@ f. HTML Entity Encode/Decode
|
|
|
168
171
|
- 支持直接回车读取剪贴板内容。
|
|
169
172
|
- 结果自动复制到剪贴板。
|
|
170
173
|
|
|
174
|
+
### 16. 占位图生成 (Placeholder Image)
|
|
175
|
+
- 选择 `g` 进入。
|
|
176
|
+
- 支持自定义:
|
|
177
|
+
- **尺寸**: 宽度和高度 (px)。
|
|
178
|
+
- **颜色**: 背景色和文字颜色(支持 Hex 或颜色名)。
|
|
179
|
+
- **内容**: 自定义图片中间的文字(默认显示尺寸)。
|
|
180
|
+
- **格式**: 输出 PNG, JPG, WebP, GIF。
|
|
181
|
+
- 文件名默认包含时间戳,避免覆盖。
|
|
182
|
+
|
|
171
183
|
## 📄 License
|
|
172
184
|
|
|
173
185
|
ISC
|
package/package.json
CHANGED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import sharp from 'sharp';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
export async function placeholderImgHandler() {
|
|
6
|
+
console.log('\n--- Generate Placeholder Image ---\n');
|
|
7
|
+
|
|
8
|
+
const answers = await inquirer.prompt([
|
|
9
|
+
{
|
|
10
|
+
type: 'input',
|
|
11
|
+
name: 'width',
|
|
12
|
+
message: 'Width (px):',
|
|
13
|
+
default: '300',
|
|
14
|
+
validate: (input) => {
|
|
15
|
+
const val = parseInt(input);
|
|
16
|
+
return !isNaN(val) && val > 0 ? true : 'Please enter a valid positive number';
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
type: 'input',
|
|
21
|
+
name: 'height',
|
|
22
|
+
message: 'Height (px):',
|
|
23
|
+
default: '200',
|
|
24
|
+
validate: (input) => {
|
|
25
|
+
const val = parseInt(input);
|
|
26
|
+
return !isNaN(val) && val > 0 ? true : 'Please enter a valid positive number';
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
type: 'input',
|
|
31
|
+
name: 'bgColor',
|
|
32
|
+
message: 'Background Color (Hex/Name):',
|
|
33
|
+
default: '#cccccc'
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
type: 'input',
|
|
37
|
+
name: 'textColor',
|
|
38
|
+
message: 'Text Color (Hex/Name):',
|
|
39
|
+
default: '#333333'
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
type: 'input',
|
|
43
|
+
name: 'text',
|
|
44
|
+
message: 'Text (leave empty for size):',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: 'list',
|
|
48
|
+
name: 'format',
|
|
49
|
+
message: 'Output Format:',
|
|
50
|
+
choices: ['png', 'jpg', 'webp', 'gif'],
|
|
51
|
+
default: 'png'
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
type: 'input',
|
|
55
|
+
name: 'filename',
|
|
56
|
+
message: 'Filename (without extension):',
|
|
57
|
+
default: () => `placeholder-${Date.now()}`
|
|
58
|
+
}
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
const width = parseInt(answers.width);
|
|
62
|
+
const height = parseInt(answers.height);
|
|
63
|
+
const text = answers.text || `${width}x${height}`;
|
|
64
|
+
const fontSize = Math.floor(Math.min(width, height) / 5); // Heuristic for font size
|
|
65
|
+
|
|
66
|
+
// Create SVG buffer
|
|
67
|
+
const svgImage = `
|
|
68
|
+
<svg width="${width}" height="${height}" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
69
|
+
<rect width="100%" height="100%" fill="${answers.bgColor}" />
|
|
70
|
+
<text x="50%" y="50%" font-size="${fontSize}" fill="${answers.textColor}" text-anchor="middle" dy=".3em" font-family="Arial, sans-serif">${text}</text>
|
|
71
|
+
</svg>
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
const buffer = Buffer.from(svgImage);
|
|
75
|
+
|
|
76
|
+
const outputFilename = `${answers.filename}.${answers.format}`;
|
|
77
|
+
const outputPath = path.resolve(process.cwd(), outputFilename);
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
await sharp(buffer)
|
|
81
|
+
.toFormat(answers.format)
|
|
82
|
+
.toFile(outputPath);
|
|
83
|
+
|
|
84
|
+
console.log(`\nImage generated successfully: ${outputPath}`);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error(`\nFailed to generate image: ${error.message}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
package/src/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import { qrcodeHandler } from './commands/qrcode.js';
|
|
|
15
15
|
import { specialCharsHandler } from './commands/specialChars.js';
|
|
16
16
|
import { emojiHandler } from './commands/emoji.js';
|
|
17
17
|
import { htmlEntitiesHandler } from './commands/htmlEntities.js';
|
|
18
|
+
import { placeholderImgHandler } from './commands/placeholderImg.js';
|
|
18
19
|
|
|
19
20
|
process.on('SIGINT', () => {
|
|
20
21
|
console.log('\nBye!');
|
|
@@ -46,7 +47,8 @@ const features = [
|
|
|
46
47
|
{ name: 'QR Code Generator', value: 'qrcode' },
|
|
47
48
|
{ name: 'Special Characters (Symbols)', value: 'specialChars' },
|
|
48
49
|
{ name: 'Emoji Picker', value: 'emoji' },
|
|
49
|
-
{ name: 'HTML Entity Encode/Decode', value: 'htmlEntities' }
|
|
50
|
+
{ name: 'HTML Entity Encode/Decode', value: 'htmlEntities' },
|
|
51
|
+
{ name: 'Placeholder Image Generator', value: 'placeholderImg' }
|
|
50
52
|
];
|
|
51
53
|
|
|
52
54
|
async function main() {
|
|
@@ -170,6 +172,9 @@ async function handleAction(action) {
|
|
|
170
172
|
case 'htmlEntities':
|
|
171
173
|
await htmlEntitiesHandler();
|
|
172
174
|
break;
|
|
175
|
+
case 'placeholderImg':
|
|
176
|
+
await placeholderImgHandler();
|
|
177
|
+
break;
|
|
173
178
|
default:
|
|
174
179
|
console.log('Feature not implemented yet.');
|
|
175
180
|
}
|