tdp2110
tdp2110

Reputation: 321

Lossless crop n drop (cut and paste) for JPEGs

I'm looking for examples/blog posts/etc of lossless jpeg operations (crop n drop = cut and paste). I know there is a program jpegtran (http://jpegclub.org/jpegtran) which can perform lossless cropping (in certain situations), but there seems to be a lack of good documentation. Yes, I have tried the google.

jpegtran also has an experimental branch that allows lossless dropping (= pasting) in certain situations, but the documentation of this seems to be even worse.

What about jpegtran's drop switch is experimental? Does it have known issues? Do people use it?

drop seems like a really cool and useful feature, and I find it odd that it's been experimental for over 10 years...

And yes, one could use lossless formats such as PNG for such operations, but I'm specifically interested in JPEGs.

Thanks!

Upvotes: 15

Views: 4021

Answers (2)

Unsigned
Unsigned

Reputation: 9916

I spent entirely too much time trying to figure this out, so here's hoping this helps someone else. This question is pretty high on Google when searching for docs on this so-called "crop 'n drop" feature.

Overview:

jpegtran -drop allows you to "drop" the blocks from one JPEG onto another JPEG.

It only replaces existing blocks, it will not expand the input, so you cannot concatenate two JPEGs with only -drop.

However, if you supply a -crop parameter larger than the input image, JPEGTran will write out blank (grey) blocks to expand to the desired size. You can then use -drop to replace these new, blank blocks with your desired image.

Behold my crappy ASCII-art example:

  1. You have two images, A.jpg and B.jpg, both have dimensions of 256x256. We want to concatenate these side-by-side to produce a 512x256 image.

    +---------+  +---------+
    |         |  |         |
    |  A.jpg  |  |  B.jpg  |
    |         |  |         |
    +---------+  +---------+
    
  2. "Uncrop" A.jpg to the size required. The -crop parameter is standard X11 geometry notation: WIDTHxHEIGHT+X+Y Positive X/Y values measure from the top/left, and negative values from the bottom/right, respectively.

    jpegtran -crop 512x256+0+0 -outfile O.jpg A.jpg
    
    +---------+---------+
    |         \         |
    |  O.jpg  \ (blank) |
    |         \         |
    +---------+---------+
    
  3. Now "drop" B.jpg into the new, blank section in O.jpg The -drop parameter uses just the origin X/Y coordinates.

    jpegtran -drop +256+0 B.jpg -outfile O.jpg O.jpg
    
    +---------+---------+    +---------+
    |         \         |    |         |
    |  O.jpg  \    o<========|  B.jpg  |
    |         \         |    |         |
    +---------+---------+    +---------+
    
  4. Done! You now have a single file, O.jpg, with dimensions of 512x256, that contains the concatenated contents of A.jpg and B.jpg

    +-------------------+
    |                   |
    |       O.jpg       |
    |                   |
    +-------------------+
    

Notes:

  • A.jpg and B.jpg must have equal height. If B.jpg is taller, it will be cut off. If A.jpg is taller, the right side of the image will have a blank strip of padding.
  • A.jpg must have a width that ends on a complete block. (Usually means divisible by 8?)
  • B.jpg may have any width, and does not have to be a multiple of the block size.

Upvotes: 21

Nicholas Shanks
Nicholas Shanks

Reputation: 10971

The jpegtran man page and the two windows apps (JpegCrop and JpegJoin) are fairly good. If you have a specific procedure you are trying to accomplish, please update your question to explain it.

Myself, I have used -drop to do lossless spriting of JPEGs on my company home page:
http://bestelec.co.uk/images/front/features.jpg

  1. First, I cropped the original photos down (on pixel boundaries) to encompass the frame required. This step can be saved losslessly using a non-JPEG format. [Art direction]
  2. I next scaled these images down to the necessary width as required by the web design. Again, saved losslessly since these are intermediate steps.
  3. Then I ran them through cjpeg with various quality options, until I found the lowest quality setting I was comfortable with.
  4. (Optional) Next I cropped the bottom edge of each reduced quality individual image to align with the penultimate MCU boundary on the vertical axis. This allowed me to join the photos in a vertical strip with no gaps. My web design doesn't require a certain height so I was free to choose one here. If your component images' extents are not aligned on MCU boundaries (as my right edges were not), be sure you are using the October 2012 build of jpegtran/JpegJoin, otherwise only the first image will show up uncropped.
  5. Lastly, I joined the images together into one jpeg, and ran the result through jpegtran -optimise -progressive -copy none to make it as small as possible, and progressive.

The net result is I have reduced three HTTP requests to one, allowing subsequent resources on the same host to be requested earlier and improving load times. This was a bigger win for me than converting the images to WebP and serving them individually, especially given that most of our corporate visitors are using IE.

Upvotes: 1

Related Questions