GithubHelp home page GithubHelp logo

dietercoopman / smart Goto Github PK

View Code? Open in Web Editor NEW
224.0 4.0 21.0 787 KB

smart makes it possible to serve images and download files from any location including Laravel disks. It enables resizing and cacheing images before sending them to the browser. Templates make it super easy to preconfigure your settings to use them all over your site.

License: MIT License

PHP 95.37% Blade 4.63%
laravel image-processing images blade

smart's Introduction

smart image manipulation

Latest Version on Packagist Downloads

Blade components for easy image manipulation and file downloads

This package makes it possible to

  • serve images from anywhere, this might be a public path , a private path or a Laravel disk
  • resize images not only by defining height and width in the html image tag but by really resizing the content that is passed to the browser
  • apply templates to images, change the settings for all images from one place
  • automatically cache your images
  • apply the full intervention/image API to an image
  • download files from anywhere, this might be a public path , a private path or a Laravel disk
  • use smart-div to add background images to div blocks

Typical use case

For smart image

Serving images that are stored wherever you want, changing the size and look&feel of an image without changing the original source. So you can use 1 image to once serve them for example grey on an overview page, but full color on a detail page.

For smart download

Downloading files that are stored wherever you want this can be your storage folder a Laravel disk or a https path

For smart div

Sometimes you have to add background images to div blocks, this can be achieved with smart-div. You can apply templates to the background images.

Watch me explaining what smart is on YouTube

Schermafbeelding 2021-12-12 om 15 26 36

Installation

You can install the package via composer

composer require dietercoopman/smart

you can optionaly publish the config file if you want to use templates or change some settings ( see advanced usage with templates )

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

Smart Image

Full example

In this example the images are stored on S3. We want the images to be served all grey and at the same height, but also rotated 15 degrees. They are encoded as webp and given a good name, search engines will love them, all with 1 smart tag.

overview

The blade component

Smart provides you with a blade component as replacement for the normal <img> html tag. You can pass in all default html attributes like the class tag they will be passed to the rendered html.

The attributes

src

Specify the source of your image with src, this can be a https path, or a location on your server ( like /mnt/images ) or a Laravel disk to unlock serving images from S3, Dropbox or other custom filesystem.

data-disk

With this data-disk attribute you tell smart on which Laravel disk the src specified can be found.

data-src

Specify the source as exposed to the browser with data-src. That is the source as shown in the rendered html, so you can expose friendly names to end users or search engines

data-template

Specify the template to apply with data-template ( see advanced usage with templates ) to apply a pre-configured template to your images.

Examples

Base example

This example will serve a file that is stored in the storage folder

<x-smart-image src="{{ storage_path('smart.png') }}"/>

Loading images from Laravel disks

This example loads an image from a S3 compatible Laravel disk with data-disk

<x-smart-image data-disk="s3" src="logos/mybrand.jpg"/>

Resizing images

This example will serve a file that is stored in the storage folder and resize it to 400px ( real file resize ! ) maintaining the aspect ratio.

<x-smart-image src="{{ storage_path('smart.png') }}" width="400px"/>

Changing the name of the served content

The default name of the served images is a cache key, if you want to give it a more friendly name you can specify it with data-src

<x-smart-image src="{{ storage_path('smart.png') }}" data-src="branding.png"/>

Using templates

With templates you can apply a predefined set of settings to your images. Typically handy if you are using images in several places of for example an e-commerce site.

<x-smart-image src="products/product1.jpg" data-template="small" data-disk="s3" data-src="friendly-product-name.jpg"/>

Caching

The images are cached with the intervention/image cache. Default, the package will generate a key to store the images in the cache. This key will be used to build the src of the file, making it possible for browsers to cache the image. This key is random generated, but you can override it if you want a more descriptive name for your images ( see data-src ) .

cache example

Advanced usage with templates

Via the data-templateattribute you can specify which template your image should use. The templates are configurable in the config/smart.php config file.

Here's the default config

<?php

return [
    'image'    => [
        'path'      => 'smart',
        'templates' => [
            'small' => [
                'resize' => [200, null, ['aspectRatio']],
            ],
            'big'   => [
                'resize' => [500, null, ['aspectRatio']],
            ]
        ],
        'file-not-found' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdj+P///38ACfsD/QVDRcoAAAAASUVORK5CYII='
    ],
    'download' => [
        'path'         => 'smart/downloads',
        'default-text' => 'download this file'
    ]
];

The path key defines the url prefix for smart, it defaults to smart but it can be whatever you want.

There are two templates defined by default, small and big. Within the configuration you can define what settings need to be applied to your images.
The possible settings are the method names as stated in the intervention image API.
You can create as many template as you want.

For example, if you want to use the resize method from intervention/image then you define a resize array with the arguments as array value, defined as a sub array. All methods from the api can be used. Here's an example of a config and the result

fullexample

if a given source is not found than the image defined in file-not-found is returned (default a 1x1 png), here you can specify any image stream or image path.

Using the full API of intervention/image

You can even go further, you can apply the full API of intervention/image by passing arrays, this examples draws a rectangle onto your resized image. The most simple way of doing it is by definig a new array with the method names of the callback as array keys and the arguments as array value, then passing this array as if you would pass a callback to an intervention/image method.

<?php

$rectangle = [
    'background' => ['rgba(255, 255, 255, 0.5)'],
    'border'     => [10, '#CCC']
];

return [
    'image' => [
        'path'      => 'smart',
        'templates' => [
            'rotated' => [
                'resize'    => [null, 500, ['aspectRatio']],
                'rectangle' => [5, 5, 195, 195, $rectangle],
            ]           
        ]
    ]
];

Smart download

Smart download makes it possible to download any type of document with a simple tag. No need to program a backend portion of code to retrieve file streams and serve them, its all handled by smart.

The blade component

Smart download provides you with a href tag. You can pass in all default html attributes like the class tag they will be passed to the rendered html.
You can use a slot as visualisation for the link, the defaults are configured in the default-text parameter from the config.

The attributes for x-smart-download

src

Specify the source of your download file with src, this can be a https path, or a location on your server ( like /mnt/images ) or a Laravel disk to unlock serving images from S3, Dropbox or other custom filesystem.

data-disk

With this data-disk attribute you tell smart on which Laravel disk the src specified can be found.

Examples

A base example

This example lets you download a manual that is stored in your storage path.

<x-smart-download src="{{ storage_path('manual.pdf') }}" target="_blank" />

An advanced example with an image as visualisation

This example combines the image and the download tag, the image is passed in the default slot so you have a visual link.

<x-smart-download src="logo.png" data-disk="s3" target="_blank" />
    <x-smart-image src="logo.png" data-template="small" data-disk="s3" />
</x-smart-download>

A rendered output example

This is the rendered output from an example as above, combining the smart-download and smart-image tag

Schermafbeelding 2021-12-11 om 14 05 07

Smart div

With smart div it's possible to apply background images on div's. The images can be stored everywhere, just like with smart-image. The documentation for smart div is the same as for smart-image. The only difference is that it will render a div with a background-image applied to it.

<x-smart-div src="smart.png" data-src="background.png"></x-smart-div>

This renders as the following html

<div style='background-image:url("/smart/background.png")'></div>

Some storytelling on use cases

<h1>Base examples</h1>
<!-- I have a file in a public path -->
<img src="smart.png" /><br />
<!-- ☝ this works, cool ... -->

<h1>Resizing images without smart</h1>
<!-- WITHOUT SMART -->
<!-- I want to make it smaller, without changeing my source -->
<img src="smart.png" width="200px" /><br/>
<!-- ☝ the file size is not changed :-( , it's the same number of KB's  76.4 KBs 
, you might don't care but ... -->

<!-- Ok lets make it some more challenging  -->
<img src="big.png" width="200px" /><br />
<!-- ☝ the file size is not changed :-( , it's the same number of KB's  445 KBs , you might care :-)
assume 25 images on your screen , thats more than 10MB ... -->

<h1>Resizing images with smart</h1>
<!-- WITH SMART -->
<!-- Let's see what smart does with the same use case -->
<x-smart-image src="smart.png" width="200px" data-src="smart.png" /><br />
<!-- ☝ the file size changed :-) , the file size is shrinked => result 12 KBs ... -->

<!-- Let's see what smart does with the same use case for the big image -->
<x-smart-image src="big.png" width="200px" data-src="big-shrinked.png" /><br />
<!-- ☝ the file size changed :-) , the file size is shrinked => result 9.4 KBs ... 
assume 25 images on your screen => 235 KBs , that's about 9.8MB less ... -->

<h1>Changing the look and feel of an image</h1>
<!-- WITHOUT SMART -->
<!-- I want to rotate the image, hmm ...  -->
<img src="smart.png" width="100px" style="transform: rotate(45deg)" /><br />
<!-- ok its rotated , but it's still too big in filesize and meh that css ... -->

<!-- WITH SMART -->
<!-- Let's see what smart does with the same use case -->
<x-smart-image src="smart.png" data-template="rotated" data-src="smart_rotated.png" /><br />
<!-- ☝ the file size changed :-) , the file size is shrinked 6.2 KBs ... -->

<h1>Advanced examples with templates</h1>
<!-- lets go crazy -->
<x-smart-image src="big.png" data-template="crazy" data-src="big-crazy.png" /><br />
<!-- ☝ fun isn't it , without touching the original image -->

<h1>Files that are not serveable by your webbrowser</h1>
<!-- And now the tought part ... not for smart but for the img tag -->

<!-- WITHOUT SMART -->
<!-- I don't want my files in that private public path , I want them on S3 -->
<img src="{{ Storage::disk('s3')->get('smart.png') }}" />
<!-- ☝ this doesn't work ... -->

<!-- WITH SMART -->
<!-- I don't want my files in that public path , I want them on S3 -->
<x-smart-image data-disk="s3" src="another_big.png" data-template="crazy" /><br />
<!-- or in your storage folder -->
<x-smart-image src="{{ storage_path('smart.png') }}" data-template="crazy" />
<!-- hell yeah ! -->

<h1>Downloads with smart</h1>
<!-- WITHOUT SMART -->
<a href="{{ Storage::disk('s3')->get('smart.png') }}" />
<!-- ☝ this doesn't work ... -->

<!-- downloads WITH SMART -->
<!-- Now , our customers might have the ability to download images -->
<x-smart-download data-disk="s3" src="another_big.png" /><br />
<!-- Or, with slots -->
<x-smart-download data-disk="s3" src="another_big.png">Download this photo</x-smart-download><br/>
<!-- Or, event better -->
<x-smart-download data-disk="s3" src="another_big.png">
    <x-smart-image data-disk="s3" src="another_big.png" data-template="crazy" />
</x-smart-download>

resize advanced downloads downloadssmart

Changelog

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

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

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

smart's People

Contributors

dietercoopman avatar laravel-shift avatar oddvalue avatar rudaovel avatar tmtung144 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

smart's Issues

smart not working in Laravel 10

I tested this package with Laravel 10, the image is displayed but with none of the configuration applied such as: resize, rotate, colorize.
I like to know what could be wrong on my end. Also, the rendered image path follows data-src instead of src attribute, which doesn't make sense to me. Path must be set to the actual path defined in the disk. Why the use of disk then?

Example:

Blade view

<x-smart-image src="6Tq99mBdQZTiLGy1udDpxkfgSWB8XjTrNJLRYLZv.jpg" data-template="rotated" data-disk="photo" data-src="6Tq99mBdQZTiLGy1udDpxkfgSWB8XjTrNJLRYLZv.jpg"/>

This above image is displayed in its full size

Blade view (not working)

<x-smart-image src="6Tq99mBdQZTiLGy1udDpxkfgSWB8XjTrNJLRYLZv.jpg" data-template="rotated" data-disk="photo" data-src="sample image.jpg"/>

The above image is not displayed

As you can see in the config below, I have to set the path to the actual directory folder as defined in the disk as well for the image to be displayed (as indicated in the first view above), although without being resized and none of the other settings applied. I thought the data-disk attribute resolves the base path for the image.

Config Setup

$rectangle = [
    'background' => ['rgba(255, 255, 255, 0.5)'],
    'border'     => [10, '#CCC']
];

return [
    'image'    => [
        'path'      => 'public/storage/photo',
        'templates' => [
            'small' => [
                'resize' => [200, null, ['aspectRatio']],
            ],
            'rotated' => [
                'resize' => [100, null, ['aspectRatio']],
                'rotate' => [-45],
                'colorize' => [-100, 0, 100],
                'rectangle' => [5, 5, 195, 195, $rectangle],
            ],
            'big'   => [
                'resize' => [500, null, ['aspectRatio']],
            ]
        ],
        'file-not-found' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdj+P///38ACfsD/QVDRcoAAAAASUVORK5CYII='
    ],
    'download' => [
        'path'         => 'public/downloads',
        'default-text' => 'download this file'
    ]
];

Any help will be much appreciated. Thank you.

Laravel 11 install failed

Intervention/imagecache is abandoned.

  Problem 1
    - illuminate/filesystem[v5.6.0, ..., v5.8.36] require php ^7.1.3 -> your php version (8.3.3) does not satisfy that requirement.
    - illuminate/filesystem[v6.0.0, ..., v6.19.1] require php ^7.2 -> your php version (8.3.3) does not satisfy that requirement.
    - intervention/imagecache 2.5.0 require php ^7.2 -> your php version (8.3.3) does not satisfy that requirement.
    - illuminate/filesystem[v7.0.0, ..., v7.28.4] require php ^7.2.5 -> your php version (8.3.3) does not satisfy that requirement.
    - illuminate/filesystem[v8.0.0, ..., v8.11.2] require php ^7.3 -> your php version (8.3.3) does not satisfy that requirement.
    - Root composer.json requires dietercoopman/smart ^1.8 -> satisfiable by dietercoopman/smart[v1.8].
    - Conclusion: don't install laravel/framework v11.0.2 (conflict analysis result)
    - Conclusion: don't install laravel/framework v11.0.3 (conflict analysis result)
    - Conclusion: don't install laravel/framework v11.0.4 (conflict analysis result)
    - Conclusion: don't install laravel/framework v11.0.5 (conflict analysis result)
    - Conclusion: don't install laravel/framework v11.0.6 (conflict analysis result)
    - Conclusion: don't install laravel/framework v11.0.7 (conflict analysis result)
    - Conclusion: don't install laravel/framework v11.0.1 (conflict analysis result)
    - dietercoopman/smart v1.8 requires intervention/imagecache ^2.5 -> satisfiable by intervention/imagecache[2.5.0, 2.5.1, 2.5.2, 2.6.0].
    - intervention/imagecache 2.6.0 requires illuminate/filesystem ^5.5|~6|~7|~8|~9|~10 -> satisfiable by illuminate/filesystem[v5.5.0, ..., v5.8.36, v6.0.0, ..., v6.20.44, v7.0.0, ..., v7.30.6, v8.0.0, ..., v8.83.27, v9.0.0, ..., v9.52.16, v10.0.0, ..., v10.48.3].
    - intervention/imagecache 2.5.2 requires illuminate/filesystem ^5.5|~6|~7|~8|~9 -> satisfiable by illuminate/filesystem[v5.5.0, ..., v5.8.36, v6.0.0, ..., v6.20.44, v7.0.0, ..., v7.30.6, v8.0.0, ..., v8.83.27, v9.0.0, ..., v9.52.16].
    - intervention/imagecache 2.5.1 requires illuminate/filesystem ^5.5|~6|~7|~8 -> satisfiable by illuminate/filesystem[v5.5.0, ..., v5.8.36, v6.0.0, ..., v6.20.44, v7.0.0, ..., v7.30.6, v8.0.0, ..., v8.83.27].
    - Only one of these can be installed: illuminate/filesystem[v5.5.0, ..., v5.8.36, v6.0.0, ..., v6.20.44, v7.0.0, ..., v7.30.6, v8.0.0, ..., v8.83.27, v9.0.0, ..., v9.52.16, v10.0.0, ..., v10.48.3, v11.0.0, ..., v11.0.7], laravel/framework[v11.0.0, ..., v11.0.7]. laravel/framework replaces illuminate/filesystem and thus cannot coexist with it.
    - Root composer.json requires laravel/framework ^11.0 -> satisfiable by laravel/framework[v11.0.0, ..., v11.0.7].

Default image

Is your feature request related to a problem? Please describe.
I will always get 1 error if the photo doesn't exist

image

Describe the solution you'd like
Please do a try catch or something to always return 1 default image (image can be white or have something like http://placehold.jp/150x150.png)

Describe alternatives you've considered
N/A

Additional context
N/A

alt attribute is missing space in front

Hi Dieter,

first off thank you for this very interesting and promising package! I have just recently discovered it through Laravel News.

For web accessibility and SEO I always try to add an alt tag to my images. You support (common) HTML attributes as part of the templates. Unfortunately the rendered output lacks a space in front of the alt tag making the rendered HTML invalid.

<x-smart-image alt="My image" width="255" height="160" src="/images/myimage.jpg" data-src="my-image.jpg" />

Expected:

<img src='/smart/my-image.jpg' alt='My image' width='255' height='160' >

Result:

<img src='/smart/my-image.jpg'alt='My image' width='255' height='160' >

Would be nice if you could fix this. Thank you!

change cache mechanisme for data-src

If you specify a data-src attribute now the code will pull the cached item from the cache and store it to a new cache variable , this is very slow. It would be better if it could be stored immediately with the correct name , so no renaming would be necessary.

Prevent package to fetch image every single time

Discussed in https://github.com/dietercoopman/smart/discussions/2

Originally posted by dietercoopman September 15, 2021
reaction on reddit by jakeydev :

Finally, does your solution 'get' the image every single time it used? So to serve an image first the server downloads it, then the users browser has to base64 decode it to view it? Seems very inefficient!

Would a better idea be downloading the private file locally - then doing your processing (resizing, reducing file size) - then serve the image file directly again? That way you get the added bonus of caching (both on the server and in browser!)?

Lazy-loading

Hey, I think it is impossible to use lazy-loading with your package.
Can I help you realize such functionality or maybe you already working on it?

I use https://github.com/aFarkas/lazysizes library for lazy loading. It is a very simple and lightweight solution.

Tweaking performance

Discussed in https://github.com/dietercoopman/smart/discussions/3

Originally posted by dietercoopman September 15, 2021
As stated on reddit by Jakeydev

Serving the images as a base64 can be pretty bad at times though. First is performance - users will not be able cache these images as they are served inline in HTML. Secondly, image sizes are now increased by around 30% - thats just base64 bloat! Users on flakey connections now need to wait extra time to download the whole document before the browser can start rendering them!

<x-smart-image src="http://shop.loc/storage/images/2021/12/07/88aaa8f34822c087065d7e0a2b55de210dd7ac0a.JPG" width="600px" />

syntax error, unexpected '=>' (T_DOUBLE_ARROW) (View: C:\OpenServer\domains\shop.loc\vendor\dietercoopman\smart\resources\views\components\smart-image.blade.php)
C:\OpenServer\domains\shop.loc\vendor\dietercoopman\smart\src\Factories\HtmlFactory.php#12
Facade\Ignition\Exceptions\ViewException
syntax error, unexpected '=>' (T_DOUBLE_ARROW)
C:\OpenServer\domains\shop.loc\vendor\dietercoopman\smart\src\Factories\HtmlFactory.php#12

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.