比如说,我想要个 图片分割并 zip 下载 的功能,但是我又不懂 canvas 也不知道浏览器能不能直接打包 zip 。只要告诉它:
生成一个 image splitter 组件,用户上传一张照片,选择行、列数量,点击按钮,就会自动分割,并打包成 zip 格式自动下载。
就会生成一个功能完整的组件:
'use client'
import React, { useState } from 'react';
import JSZip from 'jszip';
import { saveAs } from 'file-saver';
const ImageSplitter = () => {
const [image, setImage] = useState<File | null>(null);
const [rows, setRows] = useState(3);
const [cols, setCols] = useState(3);
const handleImageUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files[0]) {
setImage(e.target.files[0]);
}
};
const handleSplitImage = async () => {
if (!image) return;
const img = new Image();
img.src = URL.createObjectURL(image);
img.onload = async () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) return;
const zip = new JSZip();
const { width, height } = img;
const pieceWidth = width / cols;
const pieceHeight = height / rows;
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
canvas.width = pieceWidth;
canvas.height = pieceHeight;
ctx.drawImage(
img,
c * pieceWidth,
r * pieceHeight,
pieceWidth,
pieceHeight,
0,
0,
pieceWidth,
pieceHeight
);
const dataUrl = canvas.toDataURL('image/png');
const base64Data = dataUrl.split(',')[1];
zip.file(`piece_${r}_${c}.png`, base64Data, { base64: true });
}
}
const content = await zip.generateAsync({ type: 'blob' });
saveAs(content, 'image_pieces.zip');
};
};
return (
<div className="flex flex-col items-center justify-center p-4">
<div className="bg-white shadow-md rounded-lg p-6 w-full max-w-md">
<label className="block mb-2">
Upload an image:
<input
type="file"
accept="image/*"
onChange={handleImageUpload}
className="mb-4 w-full p-2 border border-gray-300 rounded"
/>
</label>
<label className="block mb-2">
Enter number of rows:
<input
type="number"
value={rows}
onChange={(e) => setRows(parseInt(e.target.value))}
min="1"
className="mb-4 w-full p-2 border border-gray-300 rounded"
/>
</label>
<label className="block mb-2">
Enter number of columns:
<input
type="number"
value={cols}
onChange={(e) => setCols(parseInt(e.target.value))}
min="1"
className="mb-4 w-full p-2 border border-gray-300 rounded"
/>
</label>
<button
onClick={handleSplitImage}
className="w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600 transition"
>
Split Image
</button>
</div>
</div>
);
};
export default ImageSplitter;
当然一开始样式有点丑,我补充了一句:使用 tailwind 优化一下样式,要现代感,柔色调
大体效果就出来了: https://imagesplitter.org/
1
Sniper000 79 天前 via iPhone
牛的
|
2
MaxChan 79 天前
|
3
codevvvv9 79 天前
做的好棒啊
|
4
codevvvv9 79 天前
// 生成一个 image splitter 组件,用户上传一张照片,选择行、列数量,点击按钮,就会自动分割,并打包成 zip 格式自动下载。
按上面这样操作的吗,然后直接生成代码啦? |
5
freshgoose OP @codevvvv9 #4 差不多是的,直接生成了可运行的组件
|
6
codevvvv9 76 天前
@freshgoose 那这也太强了吧
|