jcfrane/laravel-lens 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

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

jcfrane/laravel-lens

Composer 安装命令:

composer require jcfrane/laravel-lens

包简介

Configuration-driven image manipulation and caching for Laravel, inspired by LiipImagineBundle

README 文档

README

Latest Version on Packagist GitHub Tests Action Status Total Downloads License

Configuration-driven image manipulation and caching for Laravel, inspired by Symfony's LiipImagineBundle.

Define named filter sets in your config, and Laravel Lens handles the rest — lazy processing on first request, automatic caching, and simple Blade integration. Built on top of Intervention Image and Laravel's filesystem abstraction, it works with any storage driver out of the box.

Quick Examples

Define filter sets in your config:

// config/lens.php
'filter_sets' => [
    'avatar' => [
        'quality' => 80,
        'filters' => [
            ['name' => 'auto_orient'],
            ['name' => 'thumbnail', 'options' => ['size' => [150, 150], 'mode' => 'outbound']],
        ],
    ],
    'hero_banner' => [
        'quality' => 90,
        'format' => 'webp',
        'filters' => [
            ['name' => 'resize', 'options' => ['size' => [1200, null]]],
            ['name' => 'blur', 'options' => ['amount' => 5]],
        ],
    ],
],

Use them anywhere in your application:

// Blade directive
<img src="@lens('photos/profile.jpg', 'avatar')" alt="Profile" />

// Blade component
<x-lens-image path="photos/hero.jpg" filter="hero_banner" alt="Hero" class="w-full" />

// Facade
$url = Lens::url('photos/profile.jpg', 'avatar');

// API route (auto-registered)
// GET /lens/avatar/photos/profile.jpg

Features

  • Configuration-driven filter sets — define once, use everywhere
  • 14 built-in filters — thumbnail, crop, resize, scale, watermark, grayscale, flip, rotate, blur, brightness, contrast, background, strip, auto_orient
  • Lazy processing — images are processed on first request, then served from cache
  • Multiple storage drivers — works with local disk, S3, or any Laravel filesystem driver
  • Blade integration@lens() directive and <x-lens-image /> component
  • Built-in API route/lens/{filterSet}/{path} for on-demand processing
  • Cache management — Artisan commands for clearing and warming up the cache
  • Multiple drivers — GD and Imagick support via Intervention Image
  • Runtime overrides — pass options at call time without creating new filter sets
  • Extensible — register custom filters with a simple interface

Requirements

  • PHP 8.2+ (PHP 8.3+ for Laravel 13)
  • Laravel 12 or 13
  • GD or Imagick PHP extension

Installation

composer require jcfrane/laravel-lens

Publish the configuration file:

php artisan vendor:publish --tag=lens-config

Configuration

The published config file (config/lens.php) contains all settings:

Driver

'driver' => env('LENS_DRIVER', 'gd'), // 'gd' or 'imagick'

Data Loader

Configure where source images are loaded from. Uses Laravel filesystem disks:

'data_loader' => [
    'default' => 'filesystem',
    'loaders' => [
        'filesystem' => [
            'driver' => 'filesystem',
            'disk' => env('LENS_SOURCE_DISK', 'public'),
            'base_path' => '',
        ],
    ],
],

Cache

Configure where processed images are stored:

'cache' => [
    'default' => 'filesystem',
    'resolvers' => [
        'filesystem' => [
            'driver' => 'filesystem',
            'disk' => env('LENS_CACHE_DISK', 'public'),
            'base_path' => 'lens-cache',
        ],
    ],
],

Stampede Protection

When a popular image is requested before its variant is cached, many concurrent requests can each decode the full-size source into memory. Enable the lock so only one request runs the pipeline while the rest wait for the cached result:

'lock' => [
    'enabled' => env('LENS_LOCK_ENABLED', false),
    'store' => null,   // Laravel cache store for the atomic lock (null = default)
    'timeout' => 30,   // seconds the generating request may hold the lock
    'wait' => 15,      // seconds concurrent requests wait for the lock
],

Requires a cache store that supports atomic locks (redis, memcached, database, file, array, dynamodb).

Filter Sets

Each filter set defines an ordered pipeline of filters:

'filter_sets' => [
    'thumbnail_small' => [
        'quality' => 80,          // encoding quality (1-100)
        'format' => null,         // null = keep original, or 'webp', 'jpeg', 'png'
        'cache' => null,          // null = use default cache resolver
        'data_loader' => null,    // null = use default data loader
        'filters' => [
            ['name' => 'auto_orient'],
            ['name' => 'thumbnail', 'options' => [
                'size' => [150, 150],
                'mode' => 'outbound',  // 'outbound' (cover) or 'inset' (contain)
            ]],
        ],
    ],
],

Routes

'route' => [
    'enabled' => true,
    'prefix' => 'lens',
    'middleware' => ['web'],
    'signed' => false,
],

Usage

Blade Directive

<img src="@lens('photos/landscape.jpg', 'thumbnail_small')" alt="Landscape" />

Blade Component

<x-lens-image path="photos/landscape.jpg" filter="thumbnail_small" alt="Landscape" class="rounded shadow" />

The component renders an <img> tag with the filtered image URL and passes through any additional HTML attributes.

Facade

use JCFrane\LaravelLens\Facades\Lens;

// Get the URL for a filtered image
$url = Lens::url('photos/landscape.jpg', 'thumbnail_small');

// Process and cache an image immediately
$binary = Lens::resolve('photos/landscape.jpg', 'thumbnail_small');

// Check if a filtered image is cached
$cached = Lens::isCached('photos/landscape.jpg', 'thumbnail_small');

// Where the cached variant lives on the cache disk (null for no_cache)
$path = Lens::cachedPath('photos/landscape.jpg', 'thumbnail_small');
// => 'lens-cache/thumbnail_small/photos/landscape.jpg'

// Stream the cached variant as an HTTP response without loading it into
// memory (null when not cached — generate or fall back yourself)
$response = Lens::cachedResponse('photos/landscape.jpg', 'thumbnail_small', headers: [
    'Cache-Control' => 'public, max-age=31536000, immutable',
]);

// Invalidate cached images
Lens::invalidate('photos/landscape.jpg');
Lens::invalidate('photos/landscape.jpg', ['thumbnail_small']);

Runtime Filter Overrides

Override filter options at call time without creating a new filter set:

$url = Lens::url('photo.jpg', 'thumbnail_small', [
    'thumbnail' => ['size' => [200, 200]],
]);

API Route

The package auto-registers a route for on-demand image processing:

GET /lens/{filterSet}/{path}

On the first request, the image is processed through the filter pipeline and cached. Subsequent requests are served from cache with a redirect.

Example: /lens/thumbnail_small/photos/landscape.jpg

Available Filters

Filter Options Description
auto_orient Rotate based on EXIF orientation data
thumbnail size, mode, upscale Scale and/or crop to thumbnail dimensions
crop size, start Crop a rectangular region
resize size Resize to exact dimensions
scale size Scale proportionally
watermark image, position, opacity, size Overlay a watermark image
grayscale Convert to grayscale
flip direction Mirror horizontally or vertically
rotate angle, background Rotate by degrees
blur amount Apply Gaussian blur
brightness level Adjust brightness (-100 to 100)
contrast level Adjust contrast (-100 to 100)
background color, size, position Set or extend canvas with background color
strip Remove animation frames

Custom Filters

Create a class implementing FilterInterface:

use Intervention\Image\Interfaces\ImageInterface;
use JCFrane\LaravelLens\Contracts\FilterInterface;

class SepiaFilter implements FilterInterface
{
    public function apply(ImageInterface $image, array $options = []): ImageInterface
    {
        return $image->greyscale()->brightness(-10)->contrast(10);
    }

    public function name(): string
    {
        return 'sepia';
    }
}

Register it in a service provider:

use JCFrane\LaravelLens\Facades\Lens;

Lens::filterManager()->register('sepia', new SepiaFilter());

Then use it in your filter sets:

'filter_sets' => [
    'vintage' => [
        'filters' => [
            ['name' => 'sepia'],
            ['name' => 'blur', 'options' => ['amount' => 2]],
        ],
    ],
],

Artisan Commands

# Clear all cached images
php artisan lens:cache:clear

# Clear cache for a specific filter set
php artisan lens:cache:clear --filter=thumbnail_small

# Clear cache for a specific image
php artisan lens:cache:clear --path=photos/old-image.jpg

# Pre-generate cached images
php artisan lens:cache:warmup --path=photos/hero.jpg --path=photos/logo.png

# Warm up specific filter sets only
php artisan lens:cache:warmup --path=photos/hero.jpg --filter=thumbnail_small --filter=thumbnail_medium

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security-related issues, please use the issue tracker.

Credits

Acknowledgments

License

The MIT License (MIT). Please see License File for more information.

jcfrane/laravel-lens 适用场景与选型建议

jcfrane/laravel-lens 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 3 次下载、GitHub Stars 达 1, 最近一次更新时间为 2026 年 03 月 13 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「image」 「cache」 「thumbnail」 「filter」 「resize」 「laravel」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

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

围绕 jcfrane/laravel-lens 我们能提供哪些服务?
定制开发 / 二次开发

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

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

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-03-13