• Stars
    star
    492
  • Rank 89,171 (Top 2 %)
  • Language
    PHP
  • License
    MIT License
  • Created about 12 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Image thumbnail creation through specially formatted URLs for Laravel.

Croppa

Packagist

Croppa is an thumbnail generator bundle for Laravel 9.x. It follows a different approach from libraries that store your thumbnail dimensions in the model. Instead, the resizing and cropping instructions come from specially formatted urls. For instance, say you have an image with this path:

/storage/uploads/09/03/screenshot.png

To produce a 300x200 thumbnail of this, you would change the path to:

/storage/uploads/09/03/screenshot-300x200.png

This file, of course, doesn’t exist yet. Croppa listens for specifically formatted image routes and build this thumbnail on the fly, outputting the image data (with correct headers) to the browser instead of the 404 response.

At the same time, it saves the newly cropped image to the disk in the same location (the "…-300x200.png" path) that you requested. As a result, all future requests get served directly from the disk, bybassing PHP and all that overhead. In other words, your app does not boot just to serve an image. This is a differentiating point compared to other, similar libraries.

Since 4.0, Croppa lets images be stored on remote disks like S3, Dropbox, FTP and more thanks to Flysystem integration.

Server Requirements:

  • gd
  • exif - Required if you want to have Croppa auto-rotate images from devices like mobile phones based on exif meta data.

Nginx

When using Nginx HTTP server boilerplate configs, add error_page 404 = /index.php?$query_string; in the location block for Media, located in file h5bp/location/expires.conf.

# Media: images, icons, video, audio, HTC
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
  error_page 404 = /index.php?$query_string;
  expires 1M;
  access_log off;
  add_header Cache-Control "public";
}

Installation

Add Croppa to your project: composer require bkwld/croppa

Configuration

Read the source of the config file for documentation of the config options. Here are some examples of common setups (additional examples can be found here):

You can publish the config file into your app’s config directory, by running the following command:

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

Local src and crops directories

The most common scenario, the src images and their crops are created in the default ”public” Laravel disk.

return [
    'src_disk' => 'public',
    'crops_disk' => 'public',
    'path' => 'storage/(.*)$',
];

Thus, if you have <img src="{{ Croppa::url('file.jpg', 200) }}">, the returned URL will be /storage/file-200x_.jpg, the source image will be looked for at '/storage/app/public/file.jpg', and the new crop will be created at '/storage/app/public/file-200x_.jpg'. And because the URL generated by Croppa::url() points to the location where the crop was created, the web server (Apache, etc) will directly serve it on the next request (your app won’t boot just to serve an image).

Src images on S3, local crops

This is a good solution for a load balanced enviornment. Each app server will end up with it’s own cache of cropped images, so there is some wasted space. But the web server (Apache, etc) can still serve the crops directly on subsequent crop requests.

// Croppa config.php
return [
    'src_disk' => 's3',
    'crops_disk' => 'public',
    'path' => 'storage/(.*)$',
];

Thus, if you have <img src="{{ Croppa::url('file.jpg', 200, 100) }}">, the returned URL will be /storage/file-200x100.jpg, the source image will be looked for immediately within the S3 bucket that was configured as part of the Flysystem instance, and the new crop will be created at /storage/app/public/file-200x100.jpg.

Usage

The URL schema that Croppa uses is:

/path/to/image-widthxheight-option1-option2(arg1,arg2).ext

So these are all valid:

/storage/image-300x200.webp             // Crop to fit in 300x200
/storage/image-_x200.webp               // Resize to height of 200px
/storage/image-300x_.webp               // Resize to width of 300px
/storage/image-300x200-resize.webp      // Resize to fit within 300x200
/storage/image-300x200-quadrant(T).webp // See the quadrant description below

Croppa::url($url, $width, $height, $options)

To make preparing the URLs that Croppa expects an easier job, you can use the following view helper:

<img src="{{ Croppa::url($url, $width, $height, $options) }}" />
<!-- Examples (that would produce the URLs above) -->
<img src="{{ Croppa::url('storage/image.webp', 300, 200) }}" />
<img src="{{ Croppa::url('storage/image.webp', null, 200) }}" />
<img src="{{ Croppa::url('storage/image.webp', 300) }}" />
<img src="{{ Croppa::url('storage/image.webp', 300, 200, ['resize']) }}" />
<img src="{{ Croppa::url('storage/image.webp', 300, 200, ['pad']) }}" />
<img src="{{ Croppa::url('storage/image.webp', 300, 200, ['pad' => [45,168,147]]) }}" />
<img src="{{ Croppa::url('storage/image.webp', 300, 200, ['quadrant' => 'T']) }}" />
<!-- Or, if there were multiple arguments for the last example -->
<img src="{{ Croppa::url('/uploads/image.png', 300, 200, ['quadrant' => ['T']]) }}" />

These are the arguments that Croppa::url() takes:

  • $url : The URL of your source image. The path to the image relative to the src_disk will be extracted using the path config regex.
  • $width : A number or null for wildcard
  • $height : A number or null for wildcard
  • $options - An array of key value pairs, where the value is an optional array of arguments for the option. Supported option are:
    • resize - Make the image fit in the provided width and height through resizing. When omitted, the default is to crop to fit in the bounds (unless one of sides is a wildcard).
    • pad - Pad an image to desired dimensions. Moves the image into the center and fills the rest with given color. If no color is given, it will use white [255,255,255]
    • quadrant($quadrant) - Crop the remaining overflow of an image using the passed quadrant heading. The supported $quadrant values are: T - Top (good for headshots), B - Bottom, L - Left, R - Right, C - Center (default).
    • trim($x1, $y1, $x2, $y2) - Crop the source image to the size defined by the two sets of coordinates ($x1, $y1, ...) BEFORE applying the $width and $height parameters. This is designed to be used with a frontend cropping UI like jcrop so that you can respect a cropping selection that the user has defined but then output thumbnails or sized down versions of that selection with Croppa.
    • trim_perc($x1_perc, $y1_perc, $x2_perc, $y2_perc) - Has the same effect as trim() but accepts coordinates as percentages. Thus, the the upper left of the image is "0" and the bottom right of the image is "1". So if you wanted to trim the image to half the size around the center, you would add an option of trim_perc(0.25,0.25,0.75,0.75)
    • quality($int) - Set the jpeg compression quality from 0 to 100.
    • interlace($bool) - Set to 1 or 0 to turn interlacing on or off
    • upsize($bool) - Set to 1 or 0 to allow images to be upsized. If falsey and you ask for a size bigger than the source, it will only create an image as big as the original source.

Croppa::render($cropurl)

If you want to create the image programmatically you can pass to this function the url generated by Croppa::url. This will only create the thumbnail and exit.

Croppa::render('image-300x200.png');

or

Croppa::render(Croppa::url('image.png', 300, 200));

Croppa::delete($url)

You can delete a source image and all of its crops by running:

Croppa::delete('/path/to/src.png');

Croppa::reset($url)

Similar to Croppa::delete() except the source image is preserved, only the crops are deleted.

Croppa::reset('/path/to/src.png');

Console commands

croppa:purge

Deletes all crops. This works by scanning the crops_disk recursively and matching all files that have the Croppa naming convention where a corresponding src file can be found. Accepts the following options:

  • --filter - Applies a whitelisting regex filter to the crops. For example: --filter=^01/ matches all crops in the "./public/uploads/01/" directory
  • --dry-run - Ouputs the files that would be deleted to the console, but doesn’t actually remove

croppa.js

A module is included to prepare formatted URLs from JS. This can be helpful when you are creating views from JSON responses from an AJAX request; you don’t need to format the URLs on the server. It can be loaded via Require.js, CJS, or as browser global variable.

croppa.url(url, width, height, options)

Works just like the PHP Croppa::url except for how options get formatted (since JS doesn’t have associative arrays).

croppa.url('/path/to/img.jpg', 300, 200, ['resize']);
croppa.url('/path/to/img.jpg', 300, 200, ['resize', { quadrant: 'T' }]);
croppa.url('/path/to/img.jpg', 300, 200, ['resize', { quadrant: ['T'] }]);

Run php artisan asset:publish bkwld/croppa to have Laravel copy the JS to your public directory. It will go to /public/packages/bkwld/croppa/js by default.

History

Read the Github project releases for release notes.

This package uses Intervention Image to do all the image resizing. "Crop" is equivalent to it’s fit() and "resize" is … resize(). Support for interacting with non-local disks provided by Flysystem.

More Repositories

1

cloner

A trait for Laravel Eloquent models that lets you clone a model and it's relationships, including files. Even to another database.
PHP
458
star
2

decoy

A Laravel model-based CMS
PHP
303
star
3

tram

Cross-browser CSS3 transitions in JavaScript.
JavaScript
183
star
4

laravel-pug

Pug view adapter for Laravel and Lumen
PHP
159
star
5

vue-ssr-carousel

A performance focused Vue carousel designed for SSR/SSG environments.
JavaScript
131
star
6

vue-in-viewport-directive

Vue 2 directive that adds css classes when the element is the viewport
JavaScript
120
star
7

vue-in-viewport-mixin

Vue 2 mixin to determine when a DOM element is visible in the client window
JavaScript
102
star
8

vue-visual

Vue 2 image and video loader supporting lazy loading, background videos, fixed aspect ratios, low rez poster images, transitions, loaders, slotted content and more.
JavaScript
59
star
9

laravel-haml

Wraps MtHaml for ease use in Laravel
PHP
45
star
10

reporter

Generate styled logs of Laravel requests that include application timing, memory usage, input data, and sql queries
PHP
30
star
11

nuxt-stylus-resources-loader

Stylus resources (e.g. variables, mixins etc.) module for NuxtJs
JavaScript
25
star
12

upchuck

A simple, automatic handler of file uploads for Laravel's Eloquent models using using Flysystem.
PHP
22
star
13

body-scroll-toggle

Enables / disables scroll on the body
JavaScript
19
star
14

vue-height-tween-transition

Tween the height of the parent of transitioning items for use in accordions or carousels.
JavaScript
16
star
15

nuxt-spa-store-init

A simple Nuxt module that will hydrate the VueX store when running in SPA mode (not SSR)
JavaScript
15
star
16

scrapey

Get info about a URL such as you get when sharing a link on Facebook.
PHP
11
star
17

shopify-gtm-instrumentor

Helpers for sending standardized dataLayer events from a Shopify site, inspired by GA Enhanced Ecommerce.
JavaScript
11
star
18

freezer

Using Laravel, creates cached versions of full pages that can be served directly by Apache
PHP
9
star
19

nuxt-coffeescript-module

Adds Coffeescript support to your Nuxt app
JavaScript
8
star
20

vue-balance-text

A Vue directive that implements the "balance-text" package to create line breaks to make each line of text in an element equal.
JavaScript
8
star
21

vue-hamburger

A hamburger icon that transitions to a close icon
JavaScript
7
star
22

data-layer-events

Push clean events onto Google Tag Manager's dataLayer
JavaScript
7
star
23

php-library

PHP utility classes
PHP
7
star
24

stylus-library

Stylus utility mixins
Stylus
7
star
25

vue-tween-number

A Vue component that tweens a number value.
JavaScript
6
star
26

bukwild-contentful-utils

Utilities for interacting with Contentful, designed with Vue and Nuxt in mind.
JavaScript
5
star
27

lightkeeper

Averages multiple successive Lighthouse tests to arrive at a more accurate PageSpeed score
JavaScript
5
star
28

nuxt-page-transition-and-anchor-handler

Scroll to top before page transition, handle anchor links, and cross-dissolve between pages
JavaScript
4
star
29

sass-to-stylus

Script to convert a project's sass files to stylus
CoffeeScript
4
star
30

codebasehq

Tools for integrating Laravel apps with CodebaseHQ features
PHP
4
star
31

cloak

Opinionated Nuxt + Craft boilerplate
CoffeeScript
4
star
32

contentful-color-selector

A UI Extension for Contentful that generate a dropdown for selecting a space-wide color
HTML
4
star
33

vue-embed

Parse html from the CMS for use with statically generated sites
JavaScript
3
star
34

vue-in-view

Vue component for triggering animations, adding classes, firing events, and syncing slot variables based on visibility in the viewport.
JavaScript
3
star
35

sass-library

Sass utility mixins
CSS
3
star
36

create-cloak-app

Sets up a new Cloak (Nuxt + Craft/Contentful) based project.
CoffeeScript
3
star
37

vue-routing-anchor-parser

A Vue directive that parses child elements for internally linking anchor tags and binds their click events to use Vue Router's push().
JavaScript
3
star
38

buk-builder

NodeJS-based asset versioning, RequireJS build tool.
JavaScript
2
star
39

following-circles

Generative art demo using Backbone
JavaScript
2
star
40

katamari

Convert distances into terms that are more easily visualized
JavaScript
2
star
41

auto-publish

Automatically publish all Laravel workbench assets on every request
PHP
2
star
42

vscode-config

For collaborating on shared VS Code configuration.
2
star
43

asana-gitlab-bridge

Opinionated, self-hosted tool that keeps GitLab in sync with Asana
CoffeeScript
2
star
44

craft-webhook-scheduler

A Craft plugin that triggers webhooks when scheduled posts become active.
PHP
2
star
45

benchpress

Wordpress boilerplate
PHP
2
star
46

vue-unorphan

A Vue directive that implements the "unorphan" package to prevent line breaks between the last two words of an element.
JavaScript
2
star
47

craft-netlify-deploy-status

A Craft plugin that shows Netlify deploy statuses.
PHP
2
star
48

vue-detachable-header

Vue component that wraps your header and renders at the top of the viewport when scrolling up.
JavaScript
2
star
49

vue-modal

A component that renders a modal window with slotted content. Includes trapped tabbing for ADA compliance
JavaScript
1
star
50

cloak-i18n

Localization conventions for Cloak + Craft.
JavaScript
1
star
51

cloak-boilerplate

Modules that setup standard Cloak conventions.
JavaScript
1
star
52

js-library

JS utility modules
JavaScript
1
star
53

jquery-backbone-views

jQuery plugin for instantiating Backbone views from selected elements
JavaScript
1
star
54

nuxt-remote-asset-cache

Store remote assets in the local build during Nuxt generation
CoffeeScript
1
star
55

photoshop-actions

Photoshop actions we use
1
star
56

window-event-mediator

Mediator pattern for window event handling
JavaScript
1
star
57

filestack-test

Testing connecting to Filestack
PHP
1
star
58

cloak-sandbox

A simplified Cloak app for demos and experiments.
Stylus
1
star
59

vue-cover-video-component

Vue component for dynamically loading single-page HTML 5 videos
Vue
1
star
60

light-or-dark

Return whether a hex or rgb color is light or dark
JavaScript
1
star
61

react-visual

Renders images and videos into a container.
TypeScript
1
star
62

sitemap-from-routes

Generate a sitemap directly from your Laravel routes/web.php.
PHP
1
star
63

cloak-algolia

Nuxt module for syncing records to Algolia and bootstrapping Instantsearch.js
JavaScript
1
star
64

vue-media-loader-directive

Vue Directive preloads media depending on pixel density and viewport size
CoffeeScript
1
star