cocoon-dev mailing list archives

2009/1/20 Steven Dolg <steven.dolg@indoqa.com>:
> Andy Stevens schrieb:
>> 2009/1/19 Steven Dolg <steven.dolg@indoqa.com>:
>>> Vadim Gritsenko schrieb:
>>>> On Jan 15, 2009, at 9:05 AM, Reinhard Pötz wrote:
>>>> But question is, can you aggregate, include images?
>>>
>>> There is no component for that yet. But I'm confident this is easily
>>> possible.
>>
>> Interesting problem - what exactly would an "aggregate" image be? The
>> relevant parts side by side, one below the other, as separate layers
>> in a combined image? If the latter, what "mode" would you use to
>> combine them - blend/burn/multiply/as a mask - and what opacities?
>> Should they be scaled to the same size before combining or not?
>> Doesn't really fit with the usual map:aggregate/map:part without a ton
>> of extra info as to how it should be done.
>>
>
> Yes, we could easily end up with having thousands of possible ways users
> would like to use.
>
> I thought about this and implemented a simple first approach
> * use one image as the "background"
> * use one image as the "overlay"
> * define an anchor for the overlay (Center, North, South, Southeast, ...)
> relative to the background
> * allow for an additional offset to the anchor
> * draw the overlay on the background, overwriting it - but applying existing
> transparency information in the overlay
>
> [This is also the way Amazon does it:
> e.g.
> http://ecx.images-amazon.com/images/I/41CHSFA4GTL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01_.jpg
> "TopRight,35,-75" is anchor, offsetX, offsetY - try changing it, it's fun
> ;-)]
>
> In the imaging module this would look like:
> Pipeline pipeline = new NonCachingPipeline();
>
> // the background
> pipeline.addComponent(new ImageGenerator(backgroundUrl));
> // scale the background to a fixed size (to have a predictable
> "background-to-overlay" size ratio)
> pipeline.addComponent(new MaxSizeImageTransformer(200, 200));
> // apply the overlay (TopRight, slightly beyond the right and the top
> border)
> pipeline.addComponent(new AggregateImageTransformer(additionalUrl,
> Anchor.NORTHEAST, 22, -20));
> // scale again to fixed size (overlay increases image size)
> pipeline.addComponent(new MaxSizeImageTransformer(200, 200));
> // write the image
> pipeline.addComponent(new ImageSerializer());
>
> Theoretically this should allow to create what you called "combined images"
> (if I understood your idea correct) as well as the "side by side" approach.
> And this would only require 3 additional parameters (making the offset
> optional would reduce it to one required parameter).
Yes, that'd work, although it's more akin to (in the "old" ways)
<map:generate src="firstimage.jpg"/>
<map:transform type="combineimages" src="secondimage.jpg">
<map:parameter ... (settings for how to position/combine them) />
...
rather than
<map:aggregate>
<map:part src="firstimage.jpg"/>
<map:part src="secondimage.jpg"/>
...
But perhaps I should have mentioned that I've not been following the
C3 stuff, so I've no idea how things are done there... It was just
the concept of image-based pipelines rather than XML-based ones that
caught my imagination :-)
> However blend/burn/multiply/as mask would certainly require more (and me
> finding out what this actually means and how to achieve that :-) ).
I was thinking along the lines of aggregation being equivalent to
combining the images as layers, in which case there are a number of
ways they could be combined e.g. see
http://docs.gimp.org/en/gimp-concepts-layer-modes.html
> As to the scaling (or generally transforming) before combining: I guess this
> could be achieved by applying a transformation to the overlay before using
> it.
> In a sitemap this would be rather simple - with some little changes, this
> should also be possible with the pure Pipeline API, like allowing the
> AggregationImageTransformer (already existing on my machine, but yet to be
> published) to read the overlay from an InputStream which is created by
> another pipeline, or something like that.
Indeed, in the same way as before you could have had
<map:transform type="combineimages" src="cocoon:/secondimage">
where the secondimage pipeline reads secondimage.jpg and has a scaling
transformer before its serialiser.
> I still think it should be possible to provide some general purpose (and
> rather basic) transformers. As long as you can combine them, a lot of
> different effects should be possible.
> E.g. the AggregateImageTransformer will increase the image size so that both
> background and overlay are fully contained. If that's not desired, one can
> apply an CropImageTransformer afterwards, cutting of the unwanted parts.
> Of course this will require some more flexibility as some of the
> configuration of the transformers must be determined while executing the
> pipeline - but I think it should be possible in most cases...
>
>> OTOH, something like the include transformer might work better - an
>> input document describing how the images should be combined, with
>> :include elements specifying the various other input sources. But
>> then you need a pipeline that handles both XML and image data...
>> Sounds like fun ;-)
>>
>
> Not sure I understand what you mean.
> Is that like describing the image transformation in XML and having a
> transformer evaluate the XML and then process images based on that
> description?
I guess I was thinking something like how in the past you could
aggregate XML pipelines using <map:aggregate> or by using the
cinclude/xinclude transformer. So you could have an XML document,
say, with <imagecombine:include> elements that describe how to combine
the images and when you run that through the imageinclude transformer
it outputs the aggregated image. Doesn't really work with a pure
image pipeline, unless you can figure out some way to nest the include
commands in the first image (EXIF-type metadata, maybe?), hence the
use of an XML input document. But it has the advantage over a purely
pipeline-based aggregation that the images to be combined (and how to
combine them) could be generated dynamically by some other pipeline or
transformation (SQLTransformer with SELECT image, transformation FROM
IMAGE_LIST, XSLed into the relevant input document, anyone?)
> I think such an approach would limit the usage scenarios for the
> transformer, as it could not be used after some other transformation that
> returns only the resulting image.
Well, you can't put a map:aggregate after another transformation
either, you have to use the cocoon pseudo-protocol in the part's src.
Not that different.
> But I guess, we could have a transformer that is configured with an URL to
> the XML document describing the transformation. That would even allow to
> have another pipeline build that document (if that makes any sense) or
> retrieving it from somewhere else - making it easier to adjust it during
> runtime than having it directly in your code/sitemap/whatever.
>
> An interesting idea...
It's amazing how many of those you can have when you're not limited by
knowing what you're talking about ;-)
Andy.
--
http://pseudoq.sourceforge.net/