承接 mainul12501/drag-drop-crop-image-upload 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

mainul12501/drag-drop-crop-image-upload

Composer 安装命令:

composer require mainul12501/drag-drop-crop-image-upload

包简介

Laravel drag, drop, and crop image upload widget.

README 文档

README

A Laravel package that provides an elegant drag-and-drop image upload widget with built-in cropping functionality. Perfect for profile pictures, avatars, and any image upload that requires user-controlled cropping.

Latest Version on Packagist License

Features

  • Drag & drop image upload
  • Interactive image cropping with Cropper.js
  • Image rotation (90° left/right)
  • Configurable aspect ratio, dimensions, and quality
  • Base64 to file conversion with automatic format detection
  • Bootstrap modal integration support
  • Customizable labels and UI text
  • Auto-cleanup of old images on re-upload

Requirements

Requirement Version
PHP 8.1 - 8.5
Laravel 11.x, 12.x

Installation

Via Composer (Packagist)

composer require mainul12501/drag-drop-crop-image-upload

Publish the assets and configuration:

php artisan vendor:publish --tag=drag-drop-crop-assets
php artisan vendor:publish --tag=drag-drop-crop-config

Local Development

Add to your main app's composer.json:

{
    "repositories": [
        {
            "type": "path",
            "url": "packages/drag-drop-crop-image-upload"
        }
    ],
    "require": {
        "mainul/drag-drop-crop-image-upload": "*"
    }
}

Then run:

composer update
php artisan vendor:publish --tag=drag-drop-crop-assets
php artisan vendor:publish --tag=drag-drop-crop-config

Quick Start

1. Render the Widget in Your Blade View

{!! DragDropCrop::generateUpload('profile_image') !!}

2. Handle the Upload in Your Controller

use DragDropCropImageUpload\Facades\DragDropCrop;

public function store(Request $request)
{
    $imagePath = DragDropCrop::uploadFromBase64(
        $request->input('profile_image'),
        'uploads/avatars'
    );

    // Save $imagePath to your database
    User::create([
        'avatar' => $imagePath,
        // ... other fields
    ]);
}

Usage

Basic Usage

{!! DragDropCrop::generateUpload('field_name') !!}

With Custom Options

{!! DragDropCrop::generateUpload('profile_image', [
    'aspect_ratio' => 1,          // 1:1 square (use 16/9 for widescreen)
    'crop_width' => 300,          // Output width in pixels
    'crop_height' => 300,         // Output height in pixels
    'max_size_mb' => 5,           // Maximum file size in MB
    'quality' => 0.8,             // JPEG quality (0.1 to 1.0)
]) !!}

Inside Bootstrap Modal

{!! DragDropCrop::generateUpload('avatar', [
    'modal_id' => 'profileModal',  // Resets widget when modal closes
]) !!}

Custom Labels

{!! DragDropCrop::generateUpload('photo', [
    'labels' => [
        'title' => 'Upload Your Photo',
        'browse' => 'Click to select',
        'supports' => 'JPG, PNG (Max 10MB)',
        'cropped_title' => 'Preview:',
        'change' => 'Choose Different',
        'reset' => 'Start Over',
        'rotate_left' => 'Rotate Left',
        'rotate_right' => 'Rotate Right',
        'crop' => 'Crop & Save',
    ],
]) !!}

API Reference

DragDropCrop::generateUpload(string $inputName, array $options = [])

Renders the drag-drop-crop widget.

Parameters:

Parameter Type Description
$inputName string Name attribute for the hidden input containing cropped base64 data
$options array Configuration options (see below)

Options:

Option Type Default Description
id string auto-generated Unique widget identifier
file_input_name string {inputName}_file Name for the file input element
aspect_ratio float 1 Width/height ratio (1 = square, 16/9 = widescreen)
crop_width int 300 Output image width in pixels
crop_height int 300 Output image height in pixels
max_size_mb int 5 Maximum allowed file size in MB
quality float 0.8 JPEG compression quality (0.1 - 1.0)
modal_id string null Bootstrap modal ID for auto-reset on close
labels array [] Custom UI text labels

Returns: Illuminate\Support\HtmlString

DragDropCrop::uploadFromBase64(?string $base64String, ?string $directory, ?string $namePrefix, ?string $existingPath)

Converts base64 image data to a file and saves it.

Parameters:

Parameter Type Default Description
$base64String string|null - Base64-encoded image data from the widget
$directory string|null config value Upload directory relative to public/
$namePrefix string|null null Prefix for the generated filename
$existingPath string|null null Path to existing image (will be deleted)

Returns: string|null - Relative path to the uploaded file, or $existingPath if no new upload

Example with all parameters:

$path = DragDropCrop::uploadFromBase64(
    $request->input('profile_image'),  // Base64 from form
    'uploads/users',                    // Save to public/uploads/users/
    'user_' . $user->id,               // Prefix: user_123_...
    $user->current_avatar              // Delete old avatar
);

Generated filename format: {prefix}_{timestamp}_{random}.{ext}

Example: user_123_1704067200_a1b2c3d4e5.jpg

Configuration

After publishing, edit config/drag-drop-crop.php:

return [
    // Default upload directory (relative to public/)
    'upload_directory' => 'frontend/auth',

    // Default aspect ratio (1 = square)
    'aspect_ratio' => 1,

    // Default crop dimensions
    'crop_width' => 300,
    'crop_height' => 300,

    // Maximum file size in MB
    'max_size_mb' => 5,

    // JPEG compression quality (0.1 - 1.0)
    'quality' => 0.8,

    // Published assets path
    'asset_path' => 'vendor/drag-drop-crop',
];

Complete Example

Blade View (create-profile.blade.php)

<form action="{{ route('profile.store') }}" method="POST">
    @csrf

    <div class="mb-3">
        <label class="form-label">Profile Picture</label>
        {!! DragDropCrop::generateUpload('avatar', [
            'aspect_ratio' => 1,
            'crop_width' => 400,
            'crop_height' => 400,
            'max_size_mb' => 10,
            'quality' => 0.9,
            'labels' => [
                'title' => 'Drop your photo here',
                'supports' => 'JPG, PNG, GIF (Max 10MB)',
            ],
        ]) !!}
    </div>

    <div class="mb-3">
        <label class="form-label">Name</label>
        <input type="text" name="name" class="form-control">
    </div>

    <button type="submit" class="btn btn-primary">Save Profile</button>
</form>

Controller (ProfileController.php)

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use DragDropCropImageUpload\Facades\DragDropCrop;

class ProfileController extends Controller
{
    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'avatar' => 'nullable|string', // Base64 string
        ]);

        $avatarPath = null;

        if ($request->filled('avatar')) {
            $avatarPath = DragDropCrop::uploadFromBase64(
                $request->input('avatar'),
                'uploads/avatars',
                'avatar'
            );
        }

        $user = User::create([
            'name' => $request->input('name'),
            'avatar' => $avatarPath,
        ]);

        return redirect()->route('profile.show', $user)
            ->with('success', 'Profile created!');
    }

    public function update(Request $request, User $user)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'avatar' => 'nullable|string',
        ]);

        // This will delete the old avatar and upload the new one
        $avatarPath = DragDropCrop::uploadFromBase64(
            $request->input('avatar'),
            'uploads/avatars',
            'avatar_' . $user->id,
            $user->avatar  // Existing path to delete
        );

        $user->update([
            'name' => $request->input('name'),
            'avatar' => $avatarPath,
        ]);

        return redirect()->route('profile.show', $user)
            ->with('success', 'Profile updated!');
    }
}

Display the Image

@if($user->avatar)
    <img src="{{ asset($user->avatar) }}" alt="Avatar" class="rounded-circle">
@endif

Supported Image Formats

Format Extension MIME Type
JPEG .jpg image/jpeg
PNG .png image/png
GIF .gif image/gif
WebP .webp image/webp

User Interaction Flow

  1. User drags an image onto the widget (or clicks to browse)
  2. Selected image appears in the cropping interface
  3. User adjusts the crop area (drag, resize, rotate)
  4. User clicks "Crop Image" to confirm
  5. Cropped preview is shown with option to change
  6. On form submit, base64 data is sent to the server
  7. Server converts base64 to file and returns the path

License

MIT License. See LICENSE for details.

Credits

  • Cropper.js - Image cropping library
  • Built for Laravel 11 & 12

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Links

mainul12501/drag-drop-crop-image-upload 适用场景与选型建议

mainul12501/drag-drop-crop-image-upload 是一款 基于 JavaScript 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 01 月 04 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 mainul12501/drag-drop-crop-image-upload 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 mainul12501/drag-drop-crop-image-upload 我们能提供哪些服务?
定制开发 / 二次开发

基于 mainul12501/drag-drop-crop-image-upload 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 28
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: JavaScript

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-01-04