前端图片裁剪上传

前端图片裁剪上传实现方案

前端图片裁剪上传是常见的用户交互需求,涉及文件选择、图片预览、裁剪操作和上传处理等多个环节。以下是几种主流实现方式及其代码示例。

使用HTML5 Canvas实现基础裁剪

通过Canvas API可以实现基础的图片裁剪功能,适合轻量级需求。

<input type="file" id="uploader" accept="image/*">
<canvas id="canvas"></canvas>
<button id="crop-btn">裁剪并上传</button>

<script>
  const uploader = document.getElementById('uploader');
  const canvas = document.getElementById('canvas');
  const ctx = canvas.getContext('2d');
  let imageObj = null;

  uploader.addEventListener('change', (e) => {
    const file = e.target.files[0];
    const reader = new FileReader();
    
    reader.onload = (event) => {
      imageObj = new Image();
      imageObj.src = event.target.result;
      imageObj.onload = () => {
        canvas.width = 300;
        canvas.height = 300;
        ctx.drawImage(imageObj, 0, 0, 300, 300);
      };
    };
    reader.readAsDataURL(file);
  });

  document.getElementById('crop-btn').addEventListener('click', () => {
    const croppedData = canvas.toDataURL('image/jpeg');
    // 上传逻辑
    fetch('/upload', {
      method: 'POST',
      body: JSON.stringify({ image: croppedData }),
      headers: { 'Content-Type': 'application/json' }
    });
  });
</script>

使用Cropper.js专业裁剪库

Cropper.js提供了更完整的裁剪功能,包括拖拽、缩放、旋转等交互。

<link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.js"></script>

<div>
  <input type="file" id="input">
  <img id="image" style="max-width: 100%">
</div>

<script>
  const input = document.getElementById('input');
  const image = document.getElementById('image');
  let cropper;

  input.addEventListener('change', (e) => {
    if (cropper) cropper.destroy();
    
    const file = e.target.files[0];
    const reader = new FileReader();
    
    reader.onload = (event) => {
      image.src = event.target.result;
      cropper = new Cropper(image, {
        aspectRatio: 1,
        viewMode: 1
      });
    };
    reader.readAsDataURL(file);
  });

  function uploadCroppedImage() {
    cropper.getCroppedCanvas().toBlob((blob) => {
      const formData = new FormData();
      formData.append('file', blob, 'cropped.jpg');
      
      fetch('/upload', {
        method: 'POST',
        body: formData
      });
    }, 'image/jpeg');
  }
</script>

React实现方案(使用react-cropper)

对于React项目,可以使用react-cropper封装组件。

import React, { useRef, useState } from 'react';
import Cropper from 'react-cropper';
import 'cropperjs/dist/cropper.css';

function ImageUploader() {
  const [image, setImage] = useState('');
  const cropperRef = useRef(null);
  
  const handleFileChange = (e) => {
    const file = e.target.files[0];
    if (file) {
      const reader = new FileReader();
      reader.onload = () => setImage(reader.result);
      reader.readAsDataURL(file);
    }
  };

  const handleCrop = () => {
    const cropper = cropperRef.current?.cropper;
    if (cropper) {
      cropper.getCroppedCanvas().toBlob((blob) => {
        const formData = new FormData();
        formData.append('file', blob);
        // 上传逻辑
      });
    }
  };

  return (
    <div>
      <input type="file" onChange={handleFileChange} />
      <Cropper
        ref={cropperRef}
        src={image}
        style={{ height: 400, width: '100%' }}
        aspectRatio={1}
        guides={true}
      />
      <button onClick={handleCrop}>裁剪并上传</button>
    </div>
  );
}

性能优化与注意事项
  1. 限制上传文件大小:在文件选择时进行校验
if (file.size > 5 * 1024 * 1024) {
  alert('文件大小不能超过5MB');
  return;
}

  1. 压缩图片质量:减少上传体积
canvas.toBlob(callback, 'image/jpeg', 0.7); // 70%质量

  1. 显示上传进度
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (e) => {
  const percent = Math.round((e.loaded / e.total) * 100);
  console.log(`上传进度: ${percent}%`);
});

  1. 后端响应处理:建议返回CDN地址或文件存储路径
response.json().then(data => {
  console.log('文件访问地址:', data.url);
});

以上方案可根据具体项目需求进行组合或调整,现代浏览器已普遍支持这些API,但需注意移动端兼容性和性能优化。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值