New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImageMagick CLI to Wand compilator #100

Open
honzajavorek opened this Issue Mar 14, 2013 · 13 comments

Comments

5 participants
@honzajavorek

honzajavorek commented Mar 14, 2013

Just an idea, maybe silly, feel free to close this. Dive into the world of dreams and imagine following tool...

I have standard CLI command for ImageMagick:

convert test.jpg ( -clone 0 -fill '#00ff00' -colorize 100% ) ( -clone 0 -colorspace gray ) -compose blend -define compose:args=0,100 -composite test.jpg

I can do this:

from wand import cli_compiler

cmd = '''
    convert {filename}
    ( -clone 0 -fill {color} -colorize 100% )
    ( -clone 0 -colorspace gray )
    -compose blend -define compose:args=0,100
    -composite
    {filename}
'''
processor = cli_compiler(cmd)   # pre-compiles the command
processor(filename='test.jpg', color='#00ff00')  # does the job

cli_compiler would translate the command into Python code calling MagickWand API. It would also support parameters, as shown above. It returns callable, which does the job.

Is this science-fiction? I think it could be done by PLY or something, though the parser would have to be probably very complex. I don't know IM's "parameter language" so well so I could judge it from such point of view right now.


Use cases:

  • I have old code with subprocessing ImageMagick. Having such compiler, I can immediately migrate to Wand.
  • I have no further knowledge of ImageMagick and I find a tutorial on the internet how to perform what I need - of course using CLI params and convert command. I could just copy-paste it and use such compiler. Job done in 3 minutes!
@lqez

This comment has been minimized.

lqez commented Mar 14, 2013

👍

@dahlia

This comment has been minimized.

Collaborator

dahlia commented Mar 14, 2013

It’s really a brilliant idea for me, though it seems hard to be completely implemented, because there are still a lot of lacking features for Wand when it compares to ImageMagick.

Plus, I think the compiler should be possible to generate actual Python codes. It help users who don’t want to maintain command strings (which cannot be easily composed) to migrate their code to pure Wand API calls.

@suminb

This comment has been minimized.

Contributor

suminb commented Mar 15, 2013

👍

@honzajavorek

This comment has been minimized.

honzajavorek commented Mar 15, 2013

Well I wrote a simple compiler (in PLY) of custom query language into SQL (code to code) and later on I changed it so it constructs directly an object of dynamic select clause from SQLAlchemy (code to complex set of objects). It was not harder to write one or another, so I assume this to be just an implementation detail. I agree that for purposes of Wand, generation of code would be probably more helpful, it makes sense to me.

So the only stopper here is that Wand does not have complete API support? Well, we could implement what is already available and just raise NotImplementedErrors for the rest. When feature is added, it could be then (usually easily) added also to compiler. Most of people just rotate/resample images anyway...

@dahlia

This comment has been minimized.

Collaborator

dahlia commented Mar 15, 2013

I think it would be released in 0.4.0 if we start working on this.

@honzajavorek

This comment has been minimized.

honzajavorek commented Mar 15, 2013

I could help with writing the compiler. But first I suggest to start from designing the API of such feature. If it's supposed to be code generator, it could be available as standalone script, a tool for developers.

@dahlia

This comment has been minimized.

Collaborator

dahlia commented Mar 15, 2013

It could consist of two primitives and rest facades:

  1. Parser which takes an iterable of strings. (We don’t have to write a lexer for it by ourselves because shlex would be able to do it for us.) It returns a tree.
  2. Compiler which takes a tree. As like typical compilers generate IR, bytecode, or assembly, this would generate a Python code string, or ast object. We can also learn things from Jinja about this. See this talk.
  3. Facades like a shortcut interface that combines lexer and parser, interpreter interface that compiles convert command string and then immediately executes the result, migration utility that finds convert command strings in a source tree and then automatically substitutes them into Wand codes, and so on. We can imagine a lot of examples.
@honzajavorek

This comment has been minimized.

honzajavorek commented Mar 15, 2013

👍

Although I do not know Python ast objects (I know what generally AST is) or convert, it sounds like fun :-) I was always curious how Armin made Jinja without PLY, pyparsing or something like that.

@dahlia

This comment has been minimized.

Collaborator

dahlia commented Mar 15, 2013

Oh convert command string I said means our input string like this:

'''
    convert {filename}
    ( -clone 0 -fill {color} -colorize 100% )
    ( -clone 0 -colorspace gray )
    -compose blend -define compose:args=0,100
    -composite
    {filename}
'''
@dahlia

This comment has been minimized.

Collaborator

dahlia commented Mar 15, 2013

I think the reason why Armin made Jinja without any parser generators/combinators is that he want to make the syntax customizable. For example, you can use <% or [$ instead of {% token.

dahlia added a commit that referenced this issue Mar 22, 2013

Adjust roadmap again
- Deferred Python 3 compatibility to 0.4 (from 0.3).
- Add ImageMagick CLI to Wand compiler (#100).
- Add supporting __array_interface__ of NumPy (#65).
@emcconville

This comment has been minimized.

Owner

emcconville commented Apr 3, 2015

Rebooting this effort. This enhancement may be growing in complexity. It's ideal to build out a lexical analyzer, but hints of ImageMagick 7 may suggest changes in the upstream CLI parser. Also, some IM operators have different context between utility (e.g. the -format & -frame alter between identify and convert.) Building a compiler may be a really large effort.

If the original request is just to take raw CLI commands, and optional bind parameters feature, then MagickCommandGenesis could offer a straight solution. Each ImageMagick utility has it's own CLI parser, which we can "hand-off" user commands to. I'm experimenting with this method, and it seems like a valid proposal.

from wand.cli import Parser

cmd = '''
    convert {filename}
    ( -clone 0 -fill {color} -colorize 100% )
    ( -clone 0 -colorspace gray )
    -compose blend -define compose:args=0,100
    -composite
    {filename}
'''
processor = Parser(cmd)
processor(filename='test.jpg', color='#00ff00') 

Pros: Easy to implement & support
Cons: ImageMagick hijacks I/O, like stdout & stderr. (although that might be desired behavior)

@dahlia

This comment has been minimized.

Collaborator

dahlia commented Apr 4, 2015

There would be two purposes as @honzajavorek said:

  • I have old code with subprocessing ImageMagick. Having such compiler, I can immediately migrate to Wand.
  • I have no further knowledge of ImageMagick and I find a tutorial on the internet how to perform what I need - of course using CLI params and convert command. I could just copy-paste it and use such compiler. Job done in 3 minutes!

The solution proposed by @emcconville seems to solve only the former one. Although it does not mean I disagree with @emcconville. If the latter purpose does not that matter it could be a valid solution.

@dahlia dahlia modified the milestones: Very Future, 0.4.0 Apr 4, 2015

@honzajavorek

This comment has been minimized.

honzajavorek commented Apr 7, 2015

I do not do much with ImageMagick these days, but from those two use cases I see the second as more "important" nice-to-have feature, because:

  • Having old code which works isn't such a burden. Why would I want to reimplement it in Wand? For convenience? For optimization? Every case is special and needs more efforts.
  • The Internet is full of ImageMagick tutorials. You can even make yourself your very own little Instagram.

From my POV enabling convert tutorial to Python masses via Wand would be awesome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment