I have been working on a refactoring for image handling since a little while but figured I would write my thoughts down at this point and gather some feedback on it.
State currently: Media package holds media (meta) data, logic for image manipulation, thumbnails, basically everything. (Our) Imagine package is just a factory for imagine used inside the media package.
This makes it impossible to use anything else than imagine, which can be desireable in certain situations (think image manipulation services, command line tools etc.).
My idea is the following: All image manipulation code and logic resides in a respective package for the service doing the manipulation (eg. for imagine in the imagine package). Including "the" ImageService.
This (new) ImageService gets a resource and a TBD data structure describing the desired resulting resource (which would include image quality settings, "adjustments", desired image file format and more), lets call this "ImageConfiguration" for now.
To connect this with the media package we need interface which would reside in a separate package that just contains a set of interfaces for image manipulation and maybe some basic implementations/traits with reusable code (think an ImageSize object). As you can see fromt he example of the ImageSize object I would introduce more typing/objects.
The interface package could then be used to connect media with implementing packages. The media package would contain a factory for the "ImageConfiguration" (which uses the settings + adjustments entities) and for b/c reasons an ImageService that maintains the current API while internally using an injected "ImageManipulator" implementation.
That is the basic idea which
- Allows image manipulation without installing media (only the interfaces + an implementation)
- allows switching of the implementation
- Can allow further refinements and more possibilities for image handling
Some things I want to discuss:
How/What data structure to use for the "ImageConfiguration". An object would be the preferred choice, the question is how to make it generic enough to work with many implementations and at the same time specific enough to have a benefit? I guess the two mentioned areas "adjustments" and "image options" could be two properties of this object. But then the next question comes up, how to describe adjustments in a generic way?
We probably need to define "types" as a specific string" in the interface package that do something to an image (eg. resize, crop, greyscale etc.) Those should be the same across implementations. So ideally the interfaces package would predefine those + the possible default options for each, but then the interfaces package would have to be extended if you want to add something else. Maybe hybrid works, eg. we have some things predefined and then you can have a GenericAdjustment that just has a "type" and options and it's up to the implementation to figure out what to do with it...
Second what about deferral. I am thinking about remote services here, they might take a while or even want to callback when done. And I have no clue how we can deal with that, maybe someone has a great idea?
And lastly naming. I currently have a "Neos.Image.Interfaces" package in my WIP code. That could well be "Neos.ImageInterfaces" or somthing totally different. Comments, wishes?
Apart from that I can say it looks much nicer to remove the specific imagine code from the media package adjustments and classes. Might be a bit cumbersome in the first moment to take the adjustments from the DB and convert them to a generic data structure to be used by the respective implementation but it works just fine and the cost should be negligible.
If you have any other comments/requests/wishes, let me know. I have a working WIP state that is halfway into this refactoring. But I now need to flesh out the data structure for image manipulation and wanted to get some feedback on that.