Introducing qr.tl – Command Line Photoshop

http://qr.tl (pronounced ‘qwertle’) is a real time image manipulation service that lets you crop, compose, scale, tint, slice, dice images and generate QR codes without having to have any software installed on your webserver or PC.

The way it works:

In your code you generate image tags in your HTML eg. <img src=’http://qr.tl?m=INSTRUCTIONS’&gt;.

qr.tl generates images based on the instructions in the URL

eg

http://qr.tl?m=(N200x200Yellow)G10x10R1,1-8×8(Q100http://qr.tl/)O(http://img2.freeimagehosting.net/uploads/f9efc01cee.png)J

Generates

image

There is no website for qr.tl at the moment to describe the service or to help you generate your own sets of instructions, but the service is up and running and ready for you to play with.

For now if you want to use qr.tl you need to learn the instruction format. (read on 🙂 )

The master plan for the website is to create a tool that will allow you to visually create instructions based on qr.tl templates.

For now this blog post will function as the official instructions and forum.

Here are some examples with detailed descriptions to give you a basic idea of what qr.tl can do.

Some Examples

Overlay Composition

http://qr.tl?m=(http://www.watchingcw.com/wp-content/uploads/2008/07/kittens.jpg)(http://upload.wikimedia.org/wikipedia/commons/thumb/7/70/Censored_rubber_stamp.svg/550px-Censored_rubber_stamp.svg.png)O

This will overlay one image over the top of another which results in the following image.

image

If you look carefully at the URL will see that it consists of three distinct elements marked red, green and orange.

It is the execution of these instructions in the specified order that produces the end result. The aim is to end up with only one image on the stack. If you have more than one image, the server will generate an error message long the lines of.

image Not very informative ‘hopefully the next release will have something to help you debug errors in your instructions.

Now if we run through these instructions one by one.

    1. (http://www.watchingcw.com/wp-content/uploads/2008/07/kittens.jpg) Push this image onto the stack ‘this is the top and only image on the stack.
    2. (http://upload.wikimedia.org/wikipedia/commons/thumb/7/70/Censored_rubber_stamp.svg/550px-Censored_rubber_stamp.svg.png) Push this image onto the stack. This becomes the new top of the stack. There are now two images on the stack.
    3. O Executes the Overlay instruction. This will take two instructions down off the stack ‘overlay the image from the top of the stack and push the result back onto the stack.

There is also an underlay instruction U. In the previous example, if you reverse the order of the image push instructions and use the U instead of O as the last instruction you will end up with the same result.

http://qr.tl?m=(http://upload.wikimedia.org/wikipedia/commons/thumb/7/70/Censored_rubber_stamp.svg/550px-Censored_rubber_stamp.svg.png)(http://www.watchingcw.com/wp-content/uploads/2008/07/kittens.jpg)U

Generating Cropped Thumbnails

Here is another example ‘ lets say that I want to display some thumbnails on a web-site, and all I have are some larger images that are the wrong aspect ratio.

So starting with this larger image

http://silkiestar-siberian-cats.co.uk/images/kitten4.jpg

image

Can I fit it into a smaller thumbnail?

Yes.

http://qr.tl?m=(N200x200White)CZ(http://www.watchingcw.com/wp-content/uploads/2008/07/kittens.jpg)O

image

In this case we have

    1. (N200x200White) created a new 200×200 image with a white background and push that onto the stack
    2. CZ set the Cropping type to Zoom on that image’s Cropping Type register.
    3. (http://www.watchingcw.com/wp-content/uploads/2008/07/kittens.jpg) Push this image onto the stack.
    4. O Executes the Overlay instruction. This will take two instructions down off the stack overlay the image from the top of the stack and push the result back onto the stack.

In this case the cropping type instruction is the key.

You can choose CZ = Crop Zoom, CF = Crop Fit and CN = Crop None.

QR Code Generation

Here is an example of generating a QR Code.

http://qr.tl?m=(http://farm2.static.flickr.com/1336/612092698_dc7da3349b.jpg)(Qhttp://m.twitter.com/DrMiaow)J

image

Here I have taken an image and placed a QR code next to it.

    1. (http://farm2.static.flickr.com/1336/612092698_dc7da3349b.jpg) Push this this image onto the stack. Yes that’s me.
    2. (Qhttp://m.twitter.com/DrMiaow) created a QR code image that points to my twitter feed
    3. J and then joined the two images together. The default join alignment is �to the right�

Generating Lolcats

And of course what system would be complete that could not generate lolcats?

qr.tl implements the now famous  🙂 LOL-STAR markup language.

<a href=”http://qr.tl?m=(http://www.reallyfunnypictures.co.uk/animals/pics/25.08.07/tenniscat.jpg)%5BWTF!!]” temp_href=”http://qr.tl?m=(http://www.reallyfunnypictures.co.uk/animals/pics/25.08.07/tenniscat.jpg)%5BWTF!!]”>http://qr.tl?m=(http://www.reallyfunnypictures.co.uk/animals/pics/25.08.07/tenniscat.jpg)[<Oh%20hai,%20can%20Has..//>WTF!!]

image

  1. (http://www.reallyfunnypictures.co.uk/animals/pics/25.08.07/tenniscat.jpg) Push this image onto the stack
  2. [<Oh%20hai,%20can%20Has..//>WTF!!] Annotate the image using this text.

Under The Hood In Detail

Essentially the qr.tl implements a simple image processing virtual machine. The VM consists of a ‘Stack‘of images. The topmost image on the stack has Registers (variables) that can be set by other instructions. Images on the stack can be manipulated by instructions.

The instructions are specified in RPN order.

A set of qr.tl instructions is valid if it leaves one image left on the stack after all possible instructions have been executed.

There are three classes of instructions

Image Push

These are always of the form ‘(‘ something ‘)’ and they push an image onto the Stack. This new image becomes the top of the stack.

(URL) Loads an image.

eg.

(http://farm2.static.flickr.com/1336/612092698_dc7da3349b.jpg)

(NWidthxHeightColor) Creates a new image of dimensions WidthxHeight (pixels) with a background color of Color . Color is optional. Default at the moment is Transparent.

eg.

(N100x100)

(N100x100Transparent)

(N100x100Blue)

(QSizeString) Creates a QR code based on the supplied String. Size is optional.

eg.

(Qhttp://m.twitter.com/DrMiaow)

(QTesting 1 2 3)

(Q400http://m.twitter.com/DrMiaow) Create QR code that is 400×400 pixels.

Image Register Assignment

Each image on the stack has a set of registers, By executing these instructions you are able to set the registers on the topmost image.

ADigit = set alignment

This will set the alignment. Digit is any value from 0 to 9 and corresponds with the keys on a mobile phone keypad.

This has an impact on

  1. where an image is drawn when it is overlaid or underlain into a region where it does not take up all the available space.
  2. where an image is placed for a join operation.
A1 = Top Left A2 = Top Center A3 = Top Right
A4 = Left A5 = Center A6 = Right
A7 = Bottom Left A8 = Bottom A9 = Bottom Right
CType = Set cropping type.

Sets the centering algorithm

CZ = Zoom – Image will be cropped to fit the available space.

CF = Image will be fitted resized into the available space

CN = No resize

TColor = transparency color

This defines the color that will be treated as transparent

eg.

TRed

TTransparent

TOrange

GWidthxHeight = Project a grid over the topmost image on the stack that is used in combination with the Rectangle (R) instruction

eg.,

G10x10 projects a 10×10 virtual grid over the image.

RTop,Left-WidthxHeight = Set the drawing rectangle within the grid.

eg.,

R2,2-3×3 Sets the rectangle to start at position 2,2 and be 3×3 wide. The units for this on the image are defined by the Grid (G) instruction.

TTransparency = set image transparency.

This defines the value of the transparency

eg.

T.5 = 50% transparent.

T.75 = 75%

Instructions

O = Overlay

Takes the top of the stack and the next image after that on the stack, removes them from the stack. Overlays one on the other (overlays top of stack on top of  next on stack).

Overlay is influenced by several registers.

The grid and rectangle register pair defines where the overlay is performed.

The alignment register affects where the overlaid image is positioned within the rectangle.

The transparency register defines how the images are combined.

The transparency color register defines which color is treated as transparent.

U = Underlay

Takes the top of the stack and the next image after that on the stack, removes them from the stack. Overlays one on the other (underlays top of stack under next on stack).

Overlay obeys several registers.

The grid and rectangle register pair defines where the underlay is performed.

The alignment register affects how the underlaid image is aligned.

The transparency register defines how the images are combined.

The transparency color register defines which color is treated as transparent.

J = Join

Takes the top of the stack and the next image after that on the stack, removes them from the stack. Joins one image to another.

The alignment register affects how the underlaid image is aligned.

Some More Complicated Formatting

Now lets pull it all together with this example

http://qr.tl?m=(http://farm2.static.flickr.com/1336/612092698_dc7da3349b.jpg)[SMS%204223G33K//]A9G20x20R12,12-7×7(Qhttp://m.twitter.com/DrMiaow)OA8(http://assets1.twitter.com/images/twitter_logo_s.png)J

    1. (http://farm2.static.flickr.com/1336/612092698_dc7da3349b.jpg) Push this image onto the stack. Yes it’s still me.
    2. [SMS%204223G33K//] Annotate the image with the text SMS 4224G33K (I�ll leave it up to you to determine the significance of the numbers 42 and 23)
    3. A9 Set alignment to 9 (bottom right hand corner) Look at your mobile phone numeric pad.
    4. G20x20 Define a virtual 20×20 unit grid over the top of the image
    5. R12,12-7×7 Set our drawing rectangle at position 12,12 and make it 7×7 units.
    6. (Qhttp://m.twitter.com/DrMiaow)
    7. O Overlay the top of the stack onto the one below it. Removes both from the stack and pushes this new image.
    8. A8 Set alignment to 8 (bottom) Look at your mobile phone numeric pad.
    9. (http://assets1.twitter.com/images/twitter_logo_s.png) Push this image onto the stack
    10. J Join the top two images to each other., Because we are using A8 (bottom) the twitter logo (top of the stack) will be placed below the next image on the stack

Notes

Its alpha so don’t be alarmed if it spits the dummy at you at some point or gives you a cryptic error.

The most common error you will get will be-

image

… which just means that you have either left more than one image on the stack or you have executed an instruction the requires more images on the stack than you have.

At the moment the service is open for anyone to use with some restrictions on size and dimensions of the images imported and generated. If you embed any <img> tags in your HTML that link to qr.tl generation instructions – at some point in the future they will cease to work without some kind of account with qr.tl. Yes I have plans to monetise this.

Yes you can return .png or other formats, but I’m not going to say how yet.

Some browsers may require that your instructions are strictly URL encoded http://www.w3schools.com/TAGS/ref_urlencode.asp. I’ve not seen a modern browser that still has this problem -but best practice is always to ‘urlencode’ them. Url Encoding is a standard function every web development language I have seen.

I can be contacted at drmiaow@gmail.com

About James McParlane

CTO Massive Interactive. Ex Computer Whiz Kid - Now Grumpy Old Guru.
This entry was posted in LOL-STAR, qr.tl, ThumbWhere.com, Web2.0. Bookmark the permalink.

8 Responses to Introducing qr.tl – Command Line Photoshop

  1. EllisGL says:

    Text overlays are not working. Ether it just shows everything but the text, or give the "malformed instructions" message.

  2. Ben Hardy says:

    Nice job. I wrote something similar to this in C in 1993, though not nearly as feature complete, for basically doing what Photoshop’s layer mask function does with two images. Your tool here is much more flexible. Nice.

    I could use something like this for batch-mode watermarking of photos before uploading to places where they’re bound to get leeched. I imagine the transparency feature would come in handy here.

    I see your inclination for inventing languages has not decreased 🙂 Did you ever post your language for music waveform generation online somewhere? IIRC that looked like LISP, and is a great idea, especially if you consider harmonics, being able to assemble a harmonic structure algorithmically could make some bad-ass sounding notes. There are some interesting papers around on the physics of music if you’re into all that still.

  3. James says:

    I have fixed the caption issue – the change was to use the syntax

    http://qr.tl?m=INSTRUCTIONS instead of
    http://qr.tl?INSTRUCTIONS

    TA!

  4. test says:

    Someone out there is having issues with this

    http://qr.tl/?m=(N400x300White)CZ(http://i37.tinypic.com/1z48ppk.jpg)%5B<How…/>U//>doin?%5DO

    The correct url would be this.

    http://qr.tl/?m=(N400x300White)CZ(http://i37.tinypic.com/1z48ppk.jpg)%5B<How…/>U/>doin?%5DO

    A caption can only contain two of the / markers to break the caption up into [top/middle/bottom]

  5. scot says:

    Hey that’s way cool James. Should you use it an always-dynamic image link, or as a once-off generator that you save the image? The first use might break if the user gets slashdotted? Or do you cache?

    Also just as a thought, if you use a RESTFUL-style URL so that ‘http://qr.tl/?m=(N400x300White)CZ(http://i37.tinypic.com/1z48ppk.jpg)%5B<How…/>U/>doin?]O ‘ becomes something more like ‘http://qr.tl/m/N400x300WhitemCZ/http://i37.tinypic.com/1z48ppk.jpg/[<How…/>U/>doin?]/O’ … the URL becomes easily reverse-proxy cacheable (because get parameters aren’t usually cached).

  6. Thanks Scot

    Yep I cache.

    I’m looking at the possibility of a using a RESTFUL-style URL – issue is with the some of the characters I’m using in the instructions.

    ‘[‘ and ‘]’ have to go as they cause too many issues. Looking at using ” instead.

    querystring is much easier and requires far less escaping and this is more usable in the browser.

  7. This format is in testing – the caption format need to change because ‘//’ is converted into ‘/’ by some browsers and you can’t have http:// in the filename.

    eg.

    http://dev.qr.tl/(N400x300Red)/CN/(N200x200Yellow)/O/'Test

  8. abbyleem says:

    I’ve marked this article. I use instagram all the way, but instagram can’t help me create QR Code on my photos. Now I can’t wait to test add QR code on my pictures.
    Thanks for this nice sharing.

Leave a Reply to James Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s