I need to create a script, which lets user to apply some instagram-like filters to their images. First it should done in browser. Easiest way to do it are of course css3 filters. Then image should be uploaded to server, and it must be saved with exactly same filters as seen in browser.
And now the problem begins. I can do some sepia, saturated ot toaster-like effects with Image Magick, or with Image GD libraries, but results will look different from images we see in browser. "Sepia" by Image Magick is not like "sepia" we see when using css "filter: sepia();". And even worse: user may decide for a filter combination (sepia, saturated, plus toaster, plus contrast, etc.). I have almost no idea how to recreate it.
Only solution I have now, is to do "in-browser" effects without css, on canvas element (so, I can easily use the same algorithms in browser and on server). But I find this ugly, I would like to stay with css3.
Is there anywhere a good description of css filters inner architecture?
I don't think CSS would be the best way to go about it. While you can make use of plugins like CamanJS (http://camanjs.com) which make use of HTML5 Canvas but provide a whole lot of functionality and options to make your own filters or use existing ones.
However, if you still want to work with CSS. You can take a look at this CSS Filter Module Draft here which will explain exactly the inner architecture you're looking for. http://www.w3.org/TR/filter-effects/#sepiaEquivalent
i worked on filter css and filter in php. I used GD and Imagemagick, and i can tell Imagemagick is way more powerful and compatible.
First, Here is a list of blend-mode effect in css who are exaclty the same in css AND php, using Imagemagick:
for the rest, they have different mathematics formula in CSS and PHP:
Ok, now for css filter effect:
$pic->modulateImage(100, 1, 200);
$pic->setImageType (\Imagick::IMGTYPE_GRAYSCALE);
$pic_ori->sepiatoneimage(80);
-invert: $pic->negateImage(false, \Imagick::CHANNEL_ALL);
$quanta = $pic->getQuantumRange();
$pic->sigmoidalContrastImage(true, value, $quanta["quantumRangeLong"] * value, \Imagick::CHANNELL_ALL);
$tmp_background = new Imagick();
$tmp_background->newImage($pic->getImageWidth(), $pic->getImageHeight(), $color_background_image);
$opacity = new \Imagick();
$opacity->newPseudoImage($pic->getImageWidth(), $pic->getImageHeight(),"gradient:gray(100%)-gray(100%)");
$tmp_background->compositeImage($opacity, \Imagick::COMPOSITE_COPYOPACITY, 0, 0);
$pic->compositeImage($tmp_background, \Imagick::COMPOSITE_ATOP, 0, 0);
$pic->flopImage();$pic->flipImage();
</div>