Author: caefer
Date: 2010-03-14 21:19:12 +0100 (Sun, 14 Mar 2010)
New Revision: 28525

Modified:
   plugins/sfImageTransformExtraPlugin/trunk/README
Log:
first chapters of the readme

Modified: plugins/sfImageTransformExtraPlugin/trunk/README
===================================================================
--- plugins/sfImageTransformExtraPlugin/trunk/README    2010-03-14 14:09:00 UTC 
(rev 28524)
+++ plugins/sfImageTransformExtraPlugin/trunk/README    2010-03-14 20:19:12 UTC 
(rev 28525)
@@ -1,1173 +1,42 @@
-= gujThumbnailsPlugin =
+# Image manipulation made even easier - sfImageTransformExtraPlugin
 
-This plugin is the new implementation of all thumbnailing functionality for 
the WLCP. It utilises sfImageTransformPlugin to handle the transformations.
+![sfImageTransformExtraPlugin](http://www.symfony-project.org/uploads/plugins/4366ffec3f32548c30e31094c3dcbcea.png)
 
-[[BR]]
+## Introduction
 
-== Requirements ==
+On a website you ususally find lots of images and a set of formats. Say a user 
avatar is always ``80x80 PNG`` while a homepage top image is always ``320x140 
JPG`` with round corners. As it is far too costly to prepare all these 
different formats by hand there are automated ways to generate them from source 
images uploaded by a user. One of the best tools for this in the symfony world 
is the 
[sfImageTransformPlugin](http://www.symfony-project.org/plugins/sfImageTransformPlugin)
 which enables you to perform many sophisticated transformations on your images 
such as resizing, color manipulation, overlays and more.
 
- * [http://www.symfony-project.org/plugins/sfImageTransformPlugin 
sfImageTransformPlugin] from Version 1.2.0
- * [https://cmcdev.guj.de/svn/wlcp/plugins/tags/<tag_name>/gujThumbnailsPlugin 
gujThumbnailsPlugin] available since WLCP Version 1.1.5
+Using such an automatism means you have to write code and perform all 
necessary transformation on upload, no matter if the generated files are ever 
requested. It also means that design changes that also change the formats lead 
to change of business logic rather than just templates.
 
-For most transformations you need GD support compiled in your PHP binary.
+This is where sfImageTransformExtraPlugin springs to action as it provides a 
way to configure formats with multiple transformations.
+In your templates you only refer to the format by name which results in an SEO 
friendly image URL. The image itself will be generated on first request and (in 
production environments) written to the filesystem.
 
-For some you need !ImageMagick API support compiled in your PHP binary.
+Here are some of the key features:
 
-[[BR]]
+*   Configure image transformation for your thumbnail formats
+*   Format changes without the need to change code
+*   Unobstrusive implementation (No need to write code)
+*   Generating images on request
+*   Can be run as a web service for a content delivery network (CDN)
+*   Supporting image file sources from Doctrine and remote files
+*   SEO friendly URLs
+*   Generated API documentation
+*   Unit tested
+*   Easily to extend
 
-== Installation ==
+## Installation
 
-To install {{{sfImageTransformPlugin}}} please follow the installation section 
of the 
[http://www.symfony-project.org/plugins/sfImageTransformPlugin/1_2_0?tab=plugin_readme
 Readme].
+To install the plugin for a symfony project, the usual process is to use the 
symfony command line:
 
-To install {{{gujThumbnailsPlugin}}} set your SVN externals to 
[https://cmcdev.guj.de/svn/wlcp/plugins/tags/<tag_name>/gujThumbnailsPlugin].
+symfony 1.4
 
-{{{
-#!sh
-$ cd <root_of_your_project>
-$ svn propedit svn:externals plugins
-// add the following line:
-// gujThumbnailsPlugin 
https://cmcdev.guj.de/svn/wlcp/plugins/tags/<tag_name>/gujThumbnailsPlugin
-$ svn ci -m "added gujThumbnailsPlugin to this project" --non-recursive plugins
-$ svn up plugins
-}}}
+    symfony plugin:install sfImageTransformPlugin
 
-> Please replace <tag_name> with the latest WLCP version tag. 
{{{gujThumbnailsPlugin}}} is available since WLCP_1.1.5.
+Alternatively, if you don't have PEAR installed, you can download the latest 
package attached to this plugin's wiki page and extract it under your project's 
``plugins/`` directory.
 
-You have to enable them both in your projects !ProjectConfiguration class:
+Clear the cache to enable the autoloading to find the new classes:
 
-{{{
-#!php
-// in config/app/ProjectConfiguration.class.php
-[...]
-  public function setup()
-  {
-    $this->enablePlugins(array([...], 'sfImageTransformPlugin', 
'gujThumbnailsPlugin', [...]));
-  }
-[...]
-}}}
+    php symfony cc
 
-After you enabled the plugins you have also to enable the {{{gujThumb}}} 
module and the {{{Thumbnail}}} helper in your {{{settings.yml}}}:
+Note: The plugin requires sfImageTransformPlugin to be installed as well. The 
dependencies described there apply as well.
 
-{{{
-#!yml
-all:
-  .settings
-    ..
-    enabled_modules:        [default, [...], gujThumbnail]
-    ..
-    standard_helpers:       [[...], Thumbnail]
-    ..
-}}}
-
-Now it is time to run the setup task.
-
-{{{
-#!sh
-$ ./symfony wlcp:setup-thumbnailing <APPLICATION>
-}}}
-
-The task will ask you for your preferred web directory under which you want 
your thumbnails to appear.
-It defaults to {{{/thumbnails}}} or {{{/thumbs}}} if /thumbnails already 
exists (enter custom value without the leading slash).
-
-> If you just hit return and stick to the default thumbnailing will work out 
of the box.[[BR]]
-> Otherwise write down what you entered and edit your {{{app.yml}}} to set 
'''{{{thumbnails_web_dir}}}''' to the same value.[[BR]]
-> See [#Pathsanddirectories Paths and directories] for details.
-
-This task will also trigger the [#Howtotranslateyouroldthumbnailformats 
translation task]. Please follow its directions.
-
-One more clear cache for good measure and you're ready to go.
-
-{{{
-#!sh
-$ ./symfony cc
-}}}
-
-[[BR]]
-
-== Usage ==
-
-gujThumbnailsPlugin provides a helper that you can easily use to transform 
your images into thumbnails.
-
-You can load the helper in your {{{settings.yml}}} (see 
[http://www.symfony-project.org/reference/1_2/en/04-Settings#chapter_04_sub_standard_helpers
 the reference]):
-
-{{{
-#!yml
-all:
-  .settings:
-    standard_helpers: [Partial, Cache, Form, Thumbnail]
-}}}
-
-This will make the Thumbnail helper available throughout your whole project.
-
-Or you can add it to your template directly:
-
-{{{
-#!php
-<?php use_helper('Thumbnail'); ?>
-}}}
-
-To add a thumbnail to your template use this helper like this:
-
-{{{
-#!php
-<?php echo guj_thumbnail($format, $id, $name, $options = array()); ?>
-}}}
-
-This helper is very similar to symfonys {{{image_tag()}}} helper. In fact it 
uses it under the hood so you can pass all the options to {{{guj_thumbnail()}}} 
that you would pass to {{{image_tag()}}}.
-
-But instead of a $source as first parameter {{{guj_thumbnail()}}} expects you 
to provide three parameters before the options array.
-
- * '''{{{$format}}}''' references the thumbnail setting as configured in your 
app.yml
- * '''{{{$id}}}''' references the ID of your original imageAsset that you want 
to thumbnail
- * '''{{{$name}}}''' will be used to form the URL of your thumbnail for SEO 
purposes. Usually you pass the imageAssets headline attribute
- * '''{{{$options}}}''' is an array of options as you can pass it to 
{{{image_tag()}}}
-
-Example:
-{{{
-#!php
-<?php echo guj_thumbnail('gallery_thumb', $imageAsset->getId(), 
$imageAsset->headline, $options = array('align' => 'left')); ?>
-}}}
-
-Also available is a convenience method on the {{{imageAsset}}}: 
{{{imageAsset::getThumbnailTag($format, $options = array())}}}.
-It omits the {{{$id}}} and {{{$title}}} parameters and takes the values from 
{{imageAsset::getId()}}} and {{{imageAsset::headline}}}.
-
-The above example again but more convenient:
-{{{
-#!php
-<?php echo $imageAsset->getThumbnailTag('gallery_thumb', $options = 
array('align' => 'left')); ?>
-}}}
-
-[[BR]]
-
-== Configuration ==
-
-{{{gujThumbnailsPlugin}}} and its incorporated {{{sfImageTransformPlugin}}} 
come with a lot configuration possibilities.
-
-For {{{sfImageTransformPlugin}}} please refer to the configuration section of 
the 
[http://www.symfony-project.org/plugins/sfImageTransformPlugin/1_2_0?tab=plugin_readme
 Readme].
-
-{{{gujThumbnailsPlugin}}} comes with an app.yml included in the plugin. In 
most cases you will not have to change anything except for your custom 
thumbnail formats. However the following shows you how to tweak the settings to 
your requirements.
-
-[[BR]]
-
-=== Thumbnail formats ===
-
-The configuration of your thumbnail formats is a simple list of format 
identifiers (keys) with associated mime type, quality and a list of 
transformations.
-
-These transformations are yml equivalents to translation classes that come 
with {{{sfImageTransformPlugin}}} (see 
[http://svn.symfony-project.com/plugins/sfImageTransformPlugin/trunk/lib/transforms/Generic/
 Generic], 
[http://svn.symfony-project.com/plugins/sfImageTransformPlugin/trunk/lib/transforms/GD/
 GD] and 
[http://svn.symfony-project.com/plugins/sfImageTransformPlugin/trunk/lib/transforms/ImageMagick/
 ImageMagick]).
-They are very powerful and enable you not only to do resizing but also 
watermarking, writing text on images or any kind of image manipulation.
-
-Let's examine a brief example of how to configure a format for a gallery 
overview page.
-You want all thumbnails to be squares of good but not very good quality in 
jpeg format.
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    formats:
-      gallery_thumb:
-        quality:         75
-        mime_type:       image/jpg
-        transformations:
-          - { adapter: GD, transformation: thumbnail, param: { width: 150, 
height: 150, method: deflate, background: '#FFFFFF' }}
-}}}
-
- * '''{{{quality}}}''' sets the quality of the resulting thumbnail image on a 
scale from 1-100 percent.
- * '''{{{mime_type}}}''' sets the mime type of the resulting image
- * '''{{{transformations}}}''' is a list of transformations (see the "Included 
tranforms" section 
[http://www.symfony-project.org/plugins/sfImageTransformPlugin 
sfImageTransformPlugin Readme])
-
-All transformations use the same structure:
-
-  * '''{{{adapter}}}''' in most cases is the default GD but could be 
!ImageMagick. It refers to the adapter used by the configured transformations.
-  * '''{{{transformation}}}''' specifies the transformation operation to use..
-  * '''{{{param}}}''' holds all parameters that are required by the execute 
method of the specified transformation.
-
-This structure enables you to configure multiple transformations as well as 
configuring the same transformation multiple times.
-
-In the above example we have one transformation configured that resizes the 
original image on a 150x150px canvas not preserving the aspect ratio.
-
-You can configure as many transformations as you like. Multiple 
transformations will be sequentially executed.
-
-You now have a new format {{{gallery_thumb}}} that you can use in your 
templates:
-
-{{{
-#!php
-<?php echo guj_thumbnail('gallery_thumb', $imageAsset->getId(), 
$imageAsset->headline, $options = array('title' => $imageAsset->headline)); ?>
-}}}
-
-> How to convert your old thumbnail settings to the new format is described 
[#Howtotranslateyouroldthumbnailformats here].
-
-[[BR]]
-
-=== Paths and directories ===
-
-There is a number of paths and directories you can configure.
-
-[[BR]]
-
-{{{
-#!yml
-## /apps/yourapp/config/app.yml
-all:
-  gujThumbnailsPlugin:
-    thumbnails_web_dir:         /gujThumbnailsPlugin
-    id_path_depth:              3
-}}}
-
-  * '''{{{thumbnails_web_dir}}}''' defines the URL path for your thumbnails 
relative to your document root.
-  * '''{{{id_path_depth}}}''' defines the depth of the generated numeric part 
of the thumbnail URLs. A value of 2 would result in something like 
{{{/39/01/}}} while a value of 3 would result in {{{/39/01/00/}}} for the same 
image object id (in this case 139). (see [#IOUsage Concept - I/O Usage])
-
-As fonts are not directly used by {{{gujThumbnailsPlugin}}} but are in fact 
loaded within {{{sfImageTransformPlugin}}} the path to your fonts need to be 
configured in the {{{sfImageTransformPlugin}}} section of your app.yml.
-
-{{{
-#!yml
-## /apps/yourapp/config/app.yml
-all:
-  sfImageTransformPlugin:
-    ..
-    font_dir: %SF_PLUGINS_DIR%/gujThumbnailsPlugin/data/example-resources/fonts
-    ..
-}}}
-
-> Make sure that your fonts end with a lowercase extension {{{.ttf}}} as 
{{{sfImageTransformPlugin}}} currently does not recognise uppercase extensions.
-
-[[BR]]
-
-=== Caching ===
-
-gujThumbnailsPlugin implements the symfony caching API and lets you decide on 
a caching strategy.
-
-You can configure the caching behaviour in your {{{app.yml}}} just as you 
would configure a caching class for your {{{view_cache}}} in your 
[http://www.symfony-project.org/reference/1_2/en/05-Factories#chapter_05_view_cache
 factories.yml].
-
-If you don't configure a caching class gujThumbnailsPlugin defaults to 
{{{sfNoCache}}}.
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    cache:
-      class:                    gujThumbnailFileCache
-      param:
-        cache_dir:              %SF_WEB_DIR%/uploads/gujThumbnailsPlugin
-}}} 
-
-The above example is the advised caching behaviour. It stores the generated 
thumbnails in {{{/web/uploads/gujThumbnailsPlugin}}}.
-
-Already cached thumbnails will not be generated again but instead loaded from 
cache. You can use all symfony caching classes extending {{{sfCache}}} 
including APC, memcache or your own implementation.
-
-However even if you use caching serving thumbnails from cache via PHP has a 
very poor performance (way better than without caching at all but still poor). 
This is why we complement a file cache strategy with the use of Apache rewrite 
rules.
-
-[[BR]]
-
-=== Advanced: Object retrieval ===
-
-The {{{gujThumbnailsPlugin}}} is ORM independant.
-The {{{guj_thumbnail()}}} helper requires you to pass only scalar parameters 
but no object.
-
-When generating the thumbnail however the $id as passed via the URL needs to 
be instantiated and the original images source read from it. As this is heavily 
onj the ORM you use there is a way to configure retrieval:
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    get_image_factory_class:    [ baseAsset, getPeer ]
-    get_image_object_method:    factory
-    get_image_path_method:      getOriginalFilePath
-}}}
-
- * '''{{{get_image_factory_class}}}''' defines the image objects factory 
class. You have specify the class name here and {{{gujThumbnailsPlugin}}} will 
assume that {{{get_image_object_method}}} can be statically called. You can 
also pass a valid 
[http://php.net/manual/en/language.pseudo-types.php#language.types.callback 
callback] which will get instantiated and {{{get_image_object_method}}} will be 
called on the resulting object.
- * '''{{{get_image_object_method}}}''' defines the method (synamic or static. 
see above) to retrieve the image object.
- * '''{{{get_image_path_method}}}''' defined the image objects method to 
retrieve the absolute path to the image binary file.
-
-The above example would be equivalent to this:
-{{{
-#!php
-$peer       = baseAsset::getPeer();
-$object     = $peer->factory($id);
-$image_file = $object->getOriginalFilePath();
-}}}
-
-While a static example would be:
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    get_image_factory_class:    imageAssetPeer
-    get_image_object_method:    retrieveByPk
-    get_image_path_method:      get_image_path_absolute
-}}}
-
-Equivalent to:
-
-{{{
-#!php
-$object     = imageAssetPeer::retrieveByPk($id);
-$image_file = $object->get_image_path_absolute();
-}}}
-
-[[BR]]
-
-> Object retrieval is a database operation (unless the results are cached i.e. 
in memcached). It happens once for every thumbnail generation. That's why it is 
advised to use caching!
-
-[[BR]]
-
-=== Advanced: Thumbnailer ===
-
-The execution and dispatching of transformations is done in 
{{{gujThumbnailer}}} which should be suitable for all of your requirements.
-
-Though there might be some occasions that require you to implement 
[#Advanced:Complextransformationparameters Complex transformation parameters] 
or [#Howtowriteyourowntransformations Custom transformations]. If you have that 
kind of requirements you can easily extend {{{gujThumbnailer}}} and configure 
{{{gujThumbnailsPlugin}}} to use your class instead:
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    thumbnailer_class:          <yourClassName>
-}}}
-
-Let's assume you want to alter the {{{app.yml}}} parameters for your custom 
transformation {{{mytransformation}}}:
-
-{{{
-#!php
-// /lib/thumbnailer/myThumbnailer.class.php
-class myThumbnailer extends gujThumbnailer
-{
-  public function prepareParametersForMytransformation($sourceImage, 
$parameters)
-  {
-    // to something with the parameters array
-    return $parameters;
-  }
-}
-}}}
-
-Now you can use this class by setting the thumbnailer_class:
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    thumbnailer_class:          myThumbnailer
-}}}
-
-[[BR]]
-
-=== Advanced: Complex transformation parameters ===
-
-All transformation parameters can be configured in your [#Thumbnailformats 
app.yml].
-
-There are however occasions where a simple yml syntax is not enough.
-
-For example some transformations might expect an object as a parameter or for 
your overlay images you don't want to specify the resources directory for every 
overlay transformation.
-
-The solution here are callback methods defined on your [#Advanced:Thumbnailer 
thumbnailer class].
-
-For prepending the configured [#Pathsanddirectories resources directory] to 
your watermarking images {{{gujThumbnailer}}} already includes such a callback 
method: {{{prepareParametersForOverlay}}}.
-
-{{{
-#!php
-/**
- * Callback function to extend/alter parameters as given in your app.yml.
- *
- * This callback adds the resources path to an overlay image
- *
- * @param  sfImage $sourceImage The original image
- * @param  array   $parameters  Configured parameters for this transformation
- * @return array   $parameters  Extended/altered parameters
- */
-private function prepareParametersForOverlay($sourceImage, $parameters)
-{
-  if(array_key_exists('overlay', $parameters))
-  {
-    $parameters['overlay'] = new 
sfImage($this->options['resources_dir'].'/'.$parameters['overlay']);
-  }
-  return $parameters;
-}
-}}}
-
-Callback methods except two parameters, the current source image resource and 
the parameters of the current transformation.
-They return the parameters array after alteration.
-
-As a convention callback methods need to be named 
{{{prepareParametersFor<Transformation>}}} where <Transformation> is the name 
of the transformation you want to extend the parameters for.
-
-[[BR]]
-
-== Examples ==
-
-{{{gujThumbnailsPlugin}}} comes with two default formats:
-
- * '''{{{default}}}''' prints a 404 image. {{{gujThumbnailsPlugin}} will fall 
back to this when the specified format is not configured.
- * '''{{{original}}}''' will output the original image source
-
-If you want to have a look what can be done you can copy from the plugins 
{{{config/thumbnail_formats.yml.example}}} and have a look at the 
[#Howtoseeallexamplesofallformatsconfiguredinmyapplication demo].
-
-[[BR]]
-
-== Howtos ==
-
-In this section you will find common workflows and requirements to 
thumbnailing and how to deal with them.
-
-[[BR]]
-
-=== How to see all examples of all formats configured in my application ===
-
-{{{gujThumbnailsPlugin}}} comes with a demo mode that is automatically 
activated in your dev environment (and only there).
-
-It will show you examples for all thumbnail formats that are configured in 
your {{{app.yml}}}.
-
-You can browse to the demo with your dev controller only. i.e.: 
{{{http://yourdomain/dev.php/gujThumbnailsDemo}}}.
-
-[[BR]]
-
-=== How to remove generated thumbnails ===
-
-There are two ways to remove thumbnails: using the API or using a task.
-
-==== API Usage ====
-
-As thumbnails are stored using sfCache derivatives (i.e. sfFileCache, ..) we 
can use the caching API to remove thumbnails again capsulated within 
{{{gujThumbnailer}}}.
-
-To call the {{{remove()}}} method from your code you can do the following:
-
-{{{
-#!php
-$thumbnailerClass = sfConfig::get('gujThumbnailsPlugin_thumbnailer_class', 
'gujThumbnailer');
-$thumbnailer = new $thumbnailerClass();
-$thumbnailer->remove();
-}}}
-
-There are four ways of removal.
-
-{{{
-#!php
-// 1. Remove all thumbnails
-$thumbnailer->remove();
-
-// 2. Remove all thumbnails of the same format
-$thumbnailer->remove('gallery_thumb');
-
-// 3. Remove all thumbnails for a single source image ID
-$thumbnailer->remove('*', 139);
-
-// 4. Remove all thumbnails of the same format for a single source image ID 
(usually only one file)
-$thumbnailer->remove('gallery_thumb', 139);
-}}}
-
-
-==== Task Usage ====
-
-The above API can also be accessed from the commandline interface using a 
symfony task.
-
-{{{
-#!sh
-$ ./symfony help wlcp:remove-thumbnails
-//  Usage:
-//   symfony wlcp:remove-thumbnails [--env[="..."]] [--format[="..."]] 
[--id[="..."]] [--no-confirmation[="..."]] application
-//  
-//  Aliases: wlcp-remove-thumbnails
-//  
-//  Arguments:
-//   application        The application name
-//  
-//  Options:
-//   --env              The environment (default: prod)
-//   --format           Limits the removal to a single format. Defaults to 
all. (default: *)
-//   --id               Limits the removal to a single ID. Defaults to all. 
(default: *)
-//   --no-confirmation  No confirmation before removal. (default: )
-//  
-//  Description:
-//   Removes thumbnails generated by gujThumbnailsPlugin.
-//  
-//     ./symfony wlcp:remove-thumbnails <appname>
-//     Removes all (!) generated thumbnails.
-//  
-//     ./symfony wlcp:remove-thumbnails <appname> --id=123
-//     Removes all thumbnails that originate from an image with the ID '123'.
-//  
-//     ./symfony wlcp:remove-thumbnails <appname> --format=rounded_corners
-//     Removes all thumbnails of the format 'rounded_corners'.
-//  
-//     ./symfony wlcp:remove-thumbnails <appname> --format=rounded_corners 
--id=123
-//     Removes the 'rounded_corners' thumbnail for image ID '123'.
-//  
-}}}
-
-You need to pass an {{{application}}} name so that the correct app.yml is 
loaded.
-
-[[BR]]
-
-=== How to serve thumbnails from a static server domain ===
-
-Static servers are common within a 
[http://en.wikipedia.org/wiki/Content_delivery_network Content Delivery 
Network] (CDN). They are used to serve static contents like images, javascripts 
and the like. This enables you to optimise the static webserver to a maximum 
without taking care of your application as it is completely separated.
-
-You can also use commercial CDNs like 
[http://en.wikipedia.org/wiki/Akamai_Technologies Akamai].
-
-In the default installation the URLs of all generated thumbnails are build 
relative to the current document root by the {{{guj_thumbnail()}}} helper.
-
-{{{
-#!html
-<img 
src="/images/gallery_thumb/39/01/00/michelle-obama-wears-homemade-knitwear-139.png"
 />
-}}}
-
-This is the case while the {{{static_image_host}}} setting in your app.yml are 
kept to the default:
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    static_image_host:      ~
-}}}
-
- * '''{{{static_image_host}}}''' defaults to null (~) but can be set to any 
fully qualified domain.
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    static_image_host:      http://cdn-images.wlcp.de
-}}}
-
-The above would result for the same image as in the previous example like this:
-
-{{{
-#!html
-<img 
src="http://cdn-images.wlcp.de/images/gallery_thumb/39/01/00/michelle-obama-wears-homemade-knitwear-139.png";
 />
-}}}
-
-By doing this all your thumbnails will be automatically requested from 
{{{http://cdn-images.wlcp.de}}} where you can install a very lightweight 
webserver and tweak your caching settings without interfering with your 
application.
-
-> Please note that HTTP Caches often don't recognise static server domains as 
such when they are coming from the same IP address than the website itself.
-
-But we haven't yet explained how the generated thumbnails get there.
-
-There are several ways to achieve this. For once you can install your 
application twice; once for the website delivery and once for the static files. 
This way any request to a thumbnail on your static domain will lead to the 
generation of a file.
-
-You could also tweak your rewrite rules to generate thumbnails on your website 
server and make them available on your static server using a shared filesystem.
-
-Building a CDN depends much on your local settings so it is hard to give any 
advices here. However {{{gujThumbnailsPlugin}}} comes prepared.
-
-[[BR]]
-
-=== How to generate simple thumbnails ===
-
-In most cases you simply want to generate different sizes for your images. No 
special effects, so eyecandy.
-
-For this there are two transformations available: '''thumbnail''' and 
'''resize'''.
-'''thumbnail''' is just a convenient wrapper for '''resize'' and also handles 
cropping nicely.
-In most cases it will suit all your requirements.
-
-> When you want to do some more transformations your should stick to 
'''resize''' instead.
-
-The transformation '''thumbnail''' comes with some interesting methods:
-
- * '''{{{fit}}}''' will fit your image within the dimensions you configured. 
The thumbnail.will have the exact dimensions you specified while unused space 
is filled with a background color
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    formats:
-      demo_thumbnail_fit:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: thumbnail, param: { width: 100, 
height: 100, method: fit }}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(thumbnail_fit.jpg)]]
-
-[[BR]]
-
- * '''{{{scale}}}''' will fit your image within the dimensions you configured. 
The thumbnail.will then betrimmed to the area filled with the original image
-
-{{{
-#!yml
-      demo_thumbnail_scale:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: thumbnail, param: { width: 100, 
height: 100, method: scale, background: '#FF0000' }}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(thumbnail_scale.jpg)]]
-
-[[BR]]
-
- * '''{{{deflate}}}''' or '''{{{inflate}}}''' will streches your original 
image to the dimensions specified.
-
-{{{
-#!yml
-      demo_thumbnail_deflate:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: thumbnail, param: { width: 100, 
height: 100, method: deflate, background: '#FF0000' }}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(thumbnail_deflate.jpg)]]
-
-[[BR]]
-
- * '''{{{left}}}''' will center and left align the original image on the 
specified dimensions overlapping parts will be cut off.
-
-{{{
-#!yml
-      demo_thumbnail_left:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: thumbnail, param: { width: 100, 
height: 100, method: left, background: '#FF0000' }}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(thumbnail_left.jpg)]]
-
-[[BR]]
-
- * '''{{{right}}}''' will center and right align the original image on the 
specified dimensions overlapping parts will be cut off.
-
-{{{
-#!yml
-      demo_thumbnail_right:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: thumbnail, param: { width: 100, 
height: 100, method: right, background: '#FF0000' }}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(thumbnail_right.jpg)]]
-
-[[BR]]
-
- * '''{{{center}}}''' will center the original image on the specified 
dimensions overlapping parts will be cut off.
-
-{{{
-#!yml
-      demo_thumbnail_center:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: thumbnail, param: { width: 100, 
height: 100, method: center, background: '#FF0000' }}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(thumbnail_center.jpg)]]
-
-[[BR]]
-
- * '''{{{top}}}''' will center and top align the original image on the 
specified dimensions overlapping parts will be cut off.
- * '''{{{bottom}}}''' will center and bottom align the original image on the 
specified dimensions overlapping parts will be cut off.
-
-[[BR]]
-
-=== How to generate color effects on thumbnails ===
-
-In the unlikely case your design expects a certain color scheme you do have a 
lot of transformations to manipulate the colors of your images.
-
- * '''{{{brightness}}}''' will dim or light your image
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    formats:
-      demo_brightness:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: resize,     param: { width: 250, 
height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: brightness, param: { brightness: 50 
}}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(brightness.jpg)]]
-
-[[BR]]
-
- * '''{{{colorize}}}''' will tint your image in a monochrome color
-
-{{{
-#!yml
-      demo_colorize:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: resize,   param: { width: 250, 
height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: colorize, param: { red: 255, green: 
0, blue: 0, alpha: 50 }}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(colorize.jpg)]]
-
-[[BR]]
-
- * '''{{{contrast}}}''' will reduce or increase the contrast of your image
-
-{{{
-#!yml
-      demo_contrast_max:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: resize,   param: { width: 250, 
height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: contrast, param: { contrast: -80 }}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(contrast_max.jpg)]]
-
-[[BR]]
-
-{{{
-#!yml
-      demo_contrast_min:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: resize,   param: { width: 250, 
height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: contrast, param: { contrast: 50 }}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(contrast_min.jpg)]]
-
-[[BR]]
-
- * '''{{{greyscale}}}''' will transform your image to greyscale
-
-{{{
-#!yml
-      demo_greyscale:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: resize,    param: { width: 250, 
height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: greyscale, param: {}}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(greyscale.jpg)]]
-
-[[BR]]
-
- * '''{{{gamma}}}''' will do some gamma manipulation
-
-{{{
-#!yml
-      demo_gamma:
-         quality:                75
-        mime_type:              image/jpg
-        transformations:
-           - { adapter: GD, transformation: resize, param: { width: 250, 
height: 200, inflate: on, proportional: on }}
-           - { adapter: GD, transformation: gamma,  param: { input_gamma: 1.0, 
output_gamma: 1.6 }}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(gamma.jpg)]]
-
-[[BR]]
-
- * '''{{{negate}}}''' will invert your image
-
-{{{
-#!yml
-      demo_gamma:
-         quality:                75
-        mime_type:              image/jpg
-        transformations:
-           - { adapter: GD, transformation: resize, param: { width: 250, 
height: 200, inflate: on, proportional: on }}
-           - { adapter: GD, transformation: negate, param: {}}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(negate.jpg)]]
-
-[[BR]]
-
-For more advanced color manipulation you can use the following transformations:
-
-[[BR]]
-
- * '''{{{edgeDetect}}}''' manipulate your image and intensify its edges
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    formats:
-      demo_edgeDetect:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: resize,     param: { width: 250, 
height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: edgeDetect, param: {}}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(edgeDetect.jpg)]]
-
-[[BR]]
-
- * '''{{{emboss}}}''' will emboss your image
-
-{{{
-#!yml
-      demo_emboss:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: resize, param: { width: 250, 
height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: emboss, param: {}}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(emboss.jpg)]]
-
-[[BR]]
-
-=== How to twist and turn your thumbnails ===
-
-If you're not happy with the direction of an image you might want to flip, 
mirror or rotate it.
-
- * '''{{{flip}}}''' will dim or light your image
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    formats:
-      demo_flip:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: resize, param: { width: 250, 
height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: flip,   param: {}}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(flip.jpg)]]
-
-[[BR]]
-
- * '''{{{mirror}}}''' will tint your image in a monochrome color
-
-{{{
-#!yml
-      demo_mirror:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: resize, param: { width: 250, 
height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: mirror, param: {}}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(mirror.jpg)]]
-
-[[BR]]
-
- * '''{{{rotate}}}''' will reduce or increase the contrast of your image
-
-{{{
-#!yml
-      demo_rotate:
-        quality:                75
-        mime_type:              image/jpg
-        transformations:
-          - { adapter: GD, transformation: resize, param: { width: 250, 
height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: rotate, param: { angle: 50, 
background: '#00FF00' }}
-          - { adapter: GD, transformation: crop,   param: { left: 300, top: 
300, width: 250, height: 200 }}}}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(rotate.jpg)]]
-
-[[BR]]
-
-=== How to generate thumbnails with rounded corners ===
-
-What would web2.0 be without rounded corners? ;)
-
- * '''{{{rounded_corners}}}''' will round your corners transparently or with a 
specified background color.
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    formats:
-      demo_rounded_corners:
-        quality:                75
-        mime_type:              image/png
-        transformations:
-          - { adapter: GD, transformation: resize,         param: { width: 
300, height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: roundedCorners, param: { radius: 20 
}}
-}}}
-
-[[Image(original.png)]]
-[[Image(equal-sign.png)]]
-[[Image(rounded_corners.png)]]
-
-[[BR]]
-
-=== How to do watermarking ===
-
-Here's a quick example how to place a static image on top of another.
-
-The example below shows a simple overlay image that watermarks your image with 
a WLCP logo which is located in the plugins example resources directory.
-
-> To use your own overlay images you have to add them to 
{{{<pathtoyourproject>/data/resources/}}}.
-
- * '''{{{overlay}}}''' will place a (transparent) image on top of your image
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    formats:
-      demo_overlay:
-        quality:                75
-        mime_type:              image/png
-        transformations:
-          - { adapter: GD, transformation: resize,  param: { width: 250, 
height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: overlay, param: { overlay: 
overlays/wlcp.png, position: top-right }}
-}}}
-
-[[Image(original.png)]]
-[[Image(plus-sign.png)]]
-[[Image(wlcp-logo.png)]]
-[[Image(equal-sign.png)]]
-[[Image(overlay.jpg)]]
-
-[[BR]]
-
-> Another interesting way to use this transformation would be to place icons 
on teaser[[BR]]
-> images so that those teaser images could indicate if the teased article 
contains text,[[BR]]
-> audio and/or video information.[[BR]]
-
-[[BR]]
-
-=== How to apply an alpha mask ===
-
-Sometimes you have complcated designs where a rectangle image simply doesn't 
fit.
-Maybe you need a gradient in you image that smoothly dissolves into the 
background of your page or you want to do some cool eyecandy effects.
-
-{{{gujThumbnailsPlugin}}} provides a transformation for this.
-You just place your greyscale mask image into your resource folder and add the 
{{{alphaMask}}} transformation to your thumbnail format setting:
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    formats:
-      demo_alpha_mask_ pattern:
-        quality:                75
-        mime_type:              image/png
-        transformations:
-          - { adapter: GD, transformation: resize,    param: { width: 300, 
height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: alphaMask, param: { mask: 
masks/frame.gif }}
-}}}
-
-The above uses {{{masks/frame.gif}}} which comes bundled with the plugin. It 
works like this:
-
-[[Image(original.png)]]
-[[Image(plus-sign.png)]]
-[[Image(pattern.gif)]]
-[[Image(equal-sign.png)]]
-[[Image(result_pattern.png)]]
-
-[[BR]]
-
-Another example using the other bundled mask image {{{mask/pattern.gif}}}.
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    formats:
-      demo_alpha_mask_frame:
-        quality:                75
-        mime_type:              image/png
-        transformations:
-          - { adapter: GD, transformation: resize,    param: { width: 300, 
height: 200, inflate: on, proportional: on }}
-          - { adapter: GD, transformation: alphaMask, param: { mask: 
masks/pattern.gif }}
-}}}
-
-This pattern applies like this:
-
-[[Image(original.png)]]
-[[Image(plus-sign.png)]]
-[[Image(frame.gif)]]
-[[Image(equal-sign.png)]]
-[[Image(result_frame.png)]]
-
-[[BR]]
-
-=== How to write your own transformations ===
-
-It is fairly easy to write your own transformation. There is one included in 
{{{gujThumbnailsPlugin}}} that produces thumbnails with rounded corners.
-
-You simply create a new class extending {{{sfImageTransformAbstract}}}. The 
class name must begin with {{{sfImage}}} and end with the name of the adapter 
you use therein (either {{{Generic}}}, {{{GD}}} or {{{ImageMagick}}}). There 
you need to define a protected method {{{transform(sfImage $image)}}} in which 
you implement your image manipulation.
-
-{{{
-#!php
-///sfImageMyTransformationGD.class.php
-
-class sfImageMyTransformationGD extends sfImageTransformAbstract
-{
-  /**
-   * Concrete method that performs the image manipulation.
-   *
-   * @param sfImage
-   * @return sfImage
-   */
-  protected function transform(sfImage $image);
-  {
-    // implement your image manipulation code here (in this case using GD)
-    return $image;
-  }
-}
-}}}
-
-For details refer to the 'Writing your own transforms' section of the 
{{{sfImageTransformPlugin}}} 
[http://www.symfony-project.org/plugins/sfImageTransformPlugin/1_2_0?tab=plugin_readme
 Readme].
-
-> Remember that you can chain transformations in your app.yml. So don't write 
too complex transformations if the same thing can be achieved with multiple 
simple transformations as they are way more likely to be reusable.
-
-[[BR]]
-
-=== How to translate your old thumbnail formats ===
-
-Before {{{gujThumbnailsPlugin}}} there was a custom implementation of 
thumbnailing available in the {{{WLCP}}}. To configure thumbnail formats you 
added settings to your {{{app.yml}} or better still your {{{thumbnails.yml}}}.
-
-{{{gujThumbnailsPlugin}}} kept this model of configuration but changed the 
yaml format so that transformations can be applied. This results in a very 
powerful thumbnailing and image manipulation feature but also breaks backward 
compatibility so  your old thumbnail format settings won't work out of the box!
-
-There is however a new task that can translate your old settings to the new 
format.
-
-{{{
-#!sh
-$ ./symfony wlcp:translate-old-thumbnails-config <<APPLICATION_NAME>
-}}}
-
-This task will create a new file {{{thumbnail_formats.yml}}} in your 
applications config directory. You can activate it by including it in your 
{{{app.yml}}}.
-
-{{{
-#!yml
-all:
-  gujThumbnailsPlugin:
-    formats:
-<?php @include(dirname(__FILE__).'/thumbnail_formats.yml'); ?>
-}}}
-
-Now all your old formats will be available using {{{gujThumbnailsPlugin}}}.
-
-Your specific configuration to add to your {{{app.yml}}} will be output at the 
end of the task.
-
-Once you replaced all occurances of the old thumbnailing with the new one you 
can savely remove the old settings as well.
-
-[[BR]]
-
-== Concept ==
-
-[[BR]]
-
-=== Performance ===
-
-Generating thumbnails is always a heavy operation that draws on a servers 
resources. There are three precautions to limit this behaviour.
-
- 1. Generation on request [[BR]]
-    This is the easiest precaution to take. Some websites produce their 
thumbnails when the <img /> tag is generated in their HTML. This is dangerous 
as an error while generating a thumbnail will end the rendition of your web 
page. This is also a very likely behaviour as there are often multiple 
thumbnail <img /> tags on one page which ups the chances to hit a memory or 
execution time limit. [[BR]]
-    {{{gujThumbnailsPlugin}}} will generate thumbnails when they are being 
displayed within a single Apache/PHP process per thumbnail.
- 2. Caching [[BR]]
-    Using a caching class like sfFileCache enhances the overall performance as 
the generated thumbnails will be cached and served from cache instead of being 
generated again.
- 3. Content Delivery Network [[BR]]
-    As you can configure a different domain to host your thumbnails you can 
serve them from an optimised server. This is known as a static host. The tricky 
part is how tom get the thumbnails onto that server. See 
[#Howtoservethumbnailsfromastaticserverdomain How to serve thumbnails from a 
static server domain] for more details on that.
-
-[[BR]]
-
-=== I/O Usage ===
-
-Assuming that you use file caching to store your thumbnails on the local file 
system (if you't you can skip this section) you might be concerned for your I/O 
performance.
-
-It is easily possible that your website produces thousands if not millions of 
thumbnail images to be stored locally. If they would all be stored within a 
single directory almost every file system would become very inefficient as it 
will have to work a lot to manage that many inodes within on directory.
-
-This is where the ''ID path'' does its magic!
-
-In all thumbnail URLs there is a variable numeric part like {{{/39/01}}} or 
{{{/39/01/00}}} which is build from your original images ID.
-
-It automatically creates sub directories to a depth that you 
[#Pathsanddirectories configured].
-
-IDs will be zerofilled then split into chunks of 2 digits and then glued 
together again with directory separators in reverse order.
-
-{{{
-139 -> 000139 -> 00 01 39 -> /39/01/00/
-}}}
-
-You can see this id path in the follwoing example:
-
-{{{
-http://demo.wlcp.de/images/gallery_thumb/39/01/00/michelle-obama-wears-homemade-knitwear-139.png
-}}}
-
-This results in the even distribution of files to your file system.
-
-[[BR]]
-
-=== Open source strategy ===
-
-Implementing any kind of thumbnailing is an development effort. From an 
architectual perspective the efforts won't stop with the development but go 
along with a constant maintenance. Incorporating {{{sfImageTransformPlugin}}} - 
an Open Source component to symfony - reduces the efforts tremendously as it is 
already well developed and likely to be maintained by its community. The aim of 
reducing the complexity of our own developments is met by using an existing 
component.
-
-[[BR]]
-
-=== SEO considerations ===
-
-The naming scheme of the thumbnails URLs implements some SEO requirements. in 
order to find your images in i.e. Google image search images needs to have SEO 
relevant filenames and URLs. The following scheme implements [#IOUsage I/O 
thoughts] as well as a basic site structure.
-
-{{{
-http://<host>/<base_path>/<format>/##/##/[##/]<slug>-<id>.[jpg|gif|png]
-}}}
-
-With the textual {{{<slug>}}} part it also implements SEO requirements.
-
-The slug is a normalised string built from any descriptive text you have in 
store for your original image. The process of normalisation is done 
automatically and transforms every descriptive text into an SEO friendly 
filename.
-
-i.e.:
-{{{
-http://demo.wlcp.de/images/gallery_thumb/39/01/00/michelle-obama-wears-homemade-knitwear-139.png
-}}}
-
-Image searches for ''Michelle Obama'' or ''homemade knitwear'' would now 
consider your image amongst the result.
-
-[[BR]]
-
-== Next steps ==
-
-=== Integration in current and future content bridge ===
-
-One of the issues with the current content bridge is that updating an image 
binary on the CMS side does not re-generate new thumbnails.
-Moreover the changing of the images filename let to the generation of new 
thumbnails leaving the old ones still in the file system cluttering up space.
-
-As {{{gujThumbnailsPlugin}}} links thumbnails to their origin by ID only 
changes on the CMS side do lead to confusion. Also the powerfull 
[#Howtoremovegeneratedthumbnails removal feature] can now take care of 
automated removal when new versions are published.
-
-[[BR]]
-
-
-

-- 
You received this message because you are subscribed to the Google Groups 
"symfony SVN" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/symfony-svn?hl=en.

Reply via email to