From ThorxWiki
Jump to: navigation, search

Once upon a time, I was thinking about lossless jpeg editing. The sort that jpegtran can do.

jpegtran (1)         - lossless transformation of JPEG files

Specifically, jpegtran can (within limits) rotate/flip/mirror losslessly, and also crop - for values of "lossless" that only apply to the cropped image data.

And I wondered if the reverse could be true. If jpeg image data can be cropped losslessly, then it cannot rely on surrounding data. Thus surely paste is equally possible.

I researched, and found... Scroll down to the 'Mixed JPEG Quality' section where it's suggested

* use jpegtran to merge the q60 on top of the q100

So, jpegtran can do that, huh?


But an experimental version can.

That reads to me that the 'drop' option has been experimental since 2000 at least... but, let's take a look. There are helpful binaries and a sample script provided, but I had something a bit more fun in mind.

One download later, and some fiddling around... and here is this!


Counting from the bottom where it's most evident, the rows of 80 pixels high each are of quality 1, 4, 5, 6, 7, 8, 9, 10, 15, 20, 50, and hte final 144 pixels at the top are original (ie, camera sourced jpeg with text composited in and saved at quality 100).

The resulting image is 153k in size. A direct conversion of the source (captioned) image to a constant quality at quality of 72 results in an image of equivalent size.

We can also see that the q100 stripe, being 14% of the pixels, is over 60% of the final image size! (percentage can be fuzzy since the total of the cropped stripes is 148KiB, but the final image is 156KiB

$ du -c --apparent-size --block-size=1 *crop*jpg | sort -g
3158	q1crop.jpg
3238	q10crop.jpg
3292	q9crop.jpg
3478	q6crop.jpg
3509	q4crop.jpg
3553	q5crop.jpg
4011	q7crop.jpg
4120	q8crop.jpg
6245	q15crop.jpg
6552	q20crop.jpg
8155	q50crop.jpg
98768	q100crop.jpg
148079	total

$ ls -rot kwalitee.JPG 
-rw-r--r-- 1 nemo 156137 Jun 27 00:43 kwalitee.JPG

The simple script I wrote to create this final image is available in the discussion tab.

Another example image, in which I discovered that you cannot drop a colour segment onto a greyscale image (but you CAN drop a greyscale segment onto a colour image, and then subsequently drop a colour segment within the greyscale! :)

Possum final.jpg

Additional notes

In creating this, I found a few things had to be kept in mind...

  • Make sure the crops and drops are aligned on the jpeg iMCU boundaries, or headaches ensue since the crop size will be silently altered in position (as, I think, is the drop). I made all my changes on the boundary of 16x16 blocks, though 8x8 is also possible (depends on the jpeg)
  • The caption text is a light grey - I found that pure white would cause jpeg errors when dropping (DCT coefficient out of range). I don't know if this is a bug, or just a limitation in what's possible due to jpeg encoding.
  • dropping colour jpeg onto a greyscale jpeg result in greyscale. Specifically:
    • crop 'cropped.jpg' from colour source.jpg
    • create greyscale.jpg from source.jpg
    • drop 'cropped.jpg' back onto the original location within greyscale.jpg to create merged.jpg
    • merged.jpg and greyscale.jpg are binary identical!
    • note: tested just once :)

I blogged notes about this here

Personal tools

meta navigation
More thorx