比如说,我想要个 图片分割并 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/
|      1XMV2e4PmK5F85h17      2024-09-03 09:18:32 +08:00 via iPhone 牛的 | 
|      2MaxChan      2024-09-03 15:39:34 +08:00 | 
|      3codevvvv9      2024-09-03 17:26:48 +08:00 做的好棒啊 | 
|      4codevvvv9      2024-09-03 17:33:31 +08:00 // 生成一个 image splitter 组件,用户上传一张照片,选择行、列数量,点击按钮,就会自动分割,并打包成 zip 格式自动下载。 按上面这样操作的吗,然后直接生成代码啦? | 
|      5freshgoose OP @codevvvv9  #4 差不多是的,直接生成了可运行的组件 | 
|      6codevvvv9      2024-09-06 10:38:30 +08:00 @freshgoose 那这也太强了吧 |