Skip to content
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

Add a meme generator extension #93

Closed
pepijnve opened this issue Jan 15, 2016 · 19 comments
Closed

Add a meme generator extension #93

pepijnve opened this issue Jan 15, 2016 · 19 comments
Milestone

Comments

@pepijnve
Copy link
Member

Just for fun add a meme generator extension. See asciidoctor/asciidoctor-extensions-lab#8 for discussion.

meme_captain looks like a good starting point for this. The only downside is that it requires RMagick which is a native extension and as a consequence a bit of a pain to install for many users. One alternative might be to investigate if this is feasible using the command line imagemagick tools as well.

@pepijnve
Copy link
Member Author

The trivial script at https://github.com/vquaiato/memish/blob/master/memish.sh looks like a good starting point. If it's that simple, then there's probably no need to use the imagemagick api (except maybe to accelerate things a little bit).

@mojavelinux
Copy link
Member

We'll have some fun with this one. It will be especially useful in the presentations. Anything we can do to save a few clicks goes a long way.

@pepijnve
Copy link
Member Author

Played around with imagemagick a bit. The following bit of Ruby pseudo code should do the trick for a first implementation

def make_meme(background_image, top_label, bottom_label, font, output_image)
  w, h = `identify -format "%w %h" #{background_image}`
  label_width = w
  label_height = h / 5
  `convert -background none -fill white -stroke black -strokewidth 2 -font #{font} -size #{label_width}x#{label_height}  -gravity north label:'#{top_label}' top.png`
  `convert -background none -fill white -stroke black -strokewidth 2 -font #{font} -size #{label_width}x#{label_height}  -gravity south label:'#{bottom_label}' bottom.png`
  `convert #{background_image} top.png -geometry +0+0 -composite bottom.png -geometry +0+#{h - label_height} -composite #{output_image}`
end

@pepijnve pepijnve added this to the 1.4.0 milestone Jan 17, 2016
@mojavelinux
Copy link
Member

mojavelinux commented Jan 17, 2016 via email

@pepijnve
Copy link
Member Author

Definitely, but it probably wouldn't make much difference performance wise (except perhaps on Windows where process creation is a bit slower).

@pepijnve
Copy link
Member Author

Best unit test I've ever written ;)

meme::[background="man.jpg", top="I DON'T ALWAYS\\nWRITE UNIT TESTS", bottom="BUT WHEN I DO\\nTHEY GENERATE MEMES"]

gets you

2df2b8099cca300d3e6d0c3e904c42ed

@mojavelinux
Copy link
Member

Amazing! 🍻

@mojavelinux
Copy link
Member

it probably wouldn't make much difference performance wise

I agree. It's more about abstraction and keeping things self-contained where possible. I've used rmagick with success in the past.

@mojavelinux
Copy link
Member

Presentations worldwide just got crazy.

@mojavelinux
Copy link
Member

I'm thinking the background should be the target, since it's the foundation of the meme. You could also make top and bottom positional attributes:

meme::man.jpg[I DON'T ALWAYS\\nWRITE UNIT TESTS", "BUT WHEN I DO\\nTHEY GENERATE MEMES"]

caps could be an option to make typing simpler:

meme::man.jpg[I don't always\\nwrite unit tests, but when I do\\they generate memes,opts=caps]

We could use a convention of two spaces to represent a line break:

meme::man.jpg[I don't always  write unit tests, but when I do  they generate memes,opts=caps]

or we could recognize a double forward slash offset by spaces (or maybe either or)

meme::man.jpg[I don't always // write unit tests, but when I do // they generate memes,opts=caps]

line separator could even be an attribute

[line-separator=" // "]
meme::man.jpg[I don't always // write unit tests, but when I do // they generate memes,opts=caps]

wdyt?

@mojavelinux
Copy link
Member

Maybe instead of opts=caps we could do case=upper (vs case=lower).

pepijnve added a commit that referenced this issue Jan 17, 2016
@pepijnve
Copy link
Member Author

opts=upper, that's definitely one I'm going to add.

Positional attributes, good suggestion. The less clutter the better. I'm not sure how that's going to interact with the existing positional attributes that are already support (target and format are 0 and 1 for all extension at the moment), but I'll figure something out.

' // ' instead of '\n', also a good one. I'm passing the string directly to imagemagick at the moment which is why it's like that now. You're suggestion is definitely more readable.

RMagick, not sure about that yet. I would have to implement and test two code paths. The CLI variant is easier for people to get up and running I think. The only downside is that I'm currently dependant on ImageMagick. I tried real quick with GraphicsMagick, but that doesn't seem to support text auto sizing feature that ImageMagick does (or at least not with the same CLI arguments).

To be continued tomorrow. I've made a feature branch and pushed my WIP if you want to give it try already.

pepijnve added a commit that referenced this issue Jan 18, 2016
pepijnve added a commit that referenced this issue Jan 18, 2016
#93 Remove should_process? in ditaa extension
@pepijnve
Copy link
Member Author

I had a look at RMagick. Using it would avoid spawning a bunch of sub processes, but that would be the only benefit. RMagick 2 doesn't support GraphicsMagick anymore, so there's little abstraction benefit anymore. It's still also a non-FFI native extension that doesn't ship with precompiled binaries. That makes it hard to install for non-developers and difficult to use in anything but MRI.
Given those limitations I'm going to stick with calling identify and convert via subprocesses for the time being. Now if only I could remember how I used to capture subprocess output under JRuby...

@pepijnve
Copy link
Member Author

I ended up adding 'noupcase' as the option rather than 'upper'. Upper case feels like a better default for meme images.
Positional attributes and ' // ' substitution have been added as well. Looks pretty good in the asciidoc source this way (https://github.com/asciidoctor/asciidoctor-diagram/blob/meme/spec/meme_spec.rb#L16).

@pepijnve
Copy link
Member Author

I got the generator working under JRuby by using Open3s capture3 instead of capture2e.

@pepijnve
Copy link
Member Author

Merged in fbcf92e

@pepijnve
Copy link
Member Author

@timofonic not sure what you're asking here. The meme extension is already implemented. It currently depends on the imagemagick identify and convert tools.
Graphicsmagick is a fork of imagemagick that supports a different CLI interface. It's not supported at the moment.

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

No branches or pull requests

3 participants
@mojavelinux @pepijnve and others