4

Sometimes I save JPG images as uncompressed bitmap (BMP/PNG), to keep the quality when I make changes to the image.

I was wondering, is it theoretically possible to re-encode the bitmap back to its original JPG format, without losing any quality, (except for the areas I edited) ?

Edit: I was thinking somehow to brute-force it to find the original JPG information setting for that block of BMP data, and thus generating JPG out of BMP (which was JPG before) without any difference to original JPG. I don't know enough about JPG format to say if it's even possible, but I can't think why not, at least in some finite time you could brute-force 8x8 block?

Rookie
  • 4,064
  • 6
  • 54
  • 86

4 Answers4

3

JPEG compression is lossy, so you will lose some information in the .bmp when you re-encode it as a JPEG. If the image is trivial (for example 1 black pixel1 black all black for example, 1 pixel) you may be able to re-encode without loss.

You can see an example of JPEG being re-encoded multiple time here.

You can do some operations on a JPEG which are lossless, from wikipedia :

A number of alterations to a JPEG image can be performed losslessly (that is, without recompression and the associated quality loss) as long as the image size is a multiple of 1 MCU block (Minimum Coded Unit) (usually 16 pixels in both directions, for 4:2:0 chroma subsampling). Utilities that implement this include jpegtran, with user interface Jpegcrop, and the JPG_TRANSFORM plugin to IrfanView.

Blocks can be rotated in 90 degree increments, flipped in the horizontal, vertical and diagonal axes and moved about in the image. Not all blocks from the original image need to be used in the modified one.

The top and left edge of a JPEG image must lie on a 8 × 8 pixel block boundary, but the bottom and right edge need not do so. This limits the possible lossless crop operations, and also prevents flips and rotations of an image whose bottom or right edge does not lie on a block boundary for all channels (because the edge would end up on top or left, where – as aforementioned – a block boundary is obligatory).

When using lossless cropping, if the bottom or right side of the crop region is not on a block boundary then the rest of the data from the partially used blocks will still be present in the cropped file and can be recovered.

It is also possible to transform between baseline and progressive formats without any loss of quality, since the only difference is the order in which the coefficients are placed in the file.

Furthermore, several JPEG images can be losslessly joined together, as long as the edges coincide with block boundaries.

sbridges
  • 24,960
  • 4
  • 64
  • 71
  • 2
    What I'm looking for, is to somehow 'bruteforce' it to find the original JPG block information for the (8x8) BMP piece, that way converting BMP image back to JPG without any differences. When i think about this, i just think it *should* be possible - why not? – Rookie Jun 24 '13 at 18:57
2

Based on sbridges detailed answer, and a specific part of your question, I would say Yes.

(I was wondering, is it theoretically possible to re-encode the bitmap back to its original JPG format, without losing any quality, (except for the areas I edited)?)

I think the main issue here though, is that you have to edit the JPEG more directly. You lose data when you edit a block. So you could change it into a BMP to edit it, but then you'll need to keep track of (or later compare and identify) the pixels you change. Then you'll need to edit those specific blocks within the JPEG and leave all the unedited blocks untouched. That way all the unedited blocks will have no quality loss, but the blocks you changed will suffer a decode/change/recode quality loss.

Because of the complexity of actually implementing this it is possible but it may not be worth the amount of work.

BlargleMonster
  • 1,602
  • 2
  • 18
  • 33
  • The problem here isnt about the edits (i just included it here to display the usefulness of this re-encoding). The question is, is it possible, and perhaps how? It would be interesting at least. Is it really that hard? – Rookie Jun 24 '13 at 19:02
2

It is theoretically possible to losslessly encode a BMP image known to come from a JPEG format back into a JPEG format. That is, you can do the following transformation:

JPEG A => BMP X -> JPEG B => BMP X

where => is a decompression operation and -> is an compression operation.

Note that this is not quite what you are asking. You are asking the above plus that JPEG A == JPEG B. I doubt (but do not know for sure) that every JPEG representation decodes to a unique image, so my guess is that this guarantee cannot be made.

The reason it is possible to do the lossless encoding is that there is a finite number of JPEG representations of an image of a specific size and depth. This number is unmanageably large but it is nevertheless finite. An encoding algorithm could simply be to decode each one of these representations until you find the one that matches your BMP image exactly and then output that representation. The algorithm is completely impractical but shows the problem is bounded.

A practical algorithm may well exist. For example, one could imagine an iterative approach like:

  1. Choose initial compression parameters (color sampling and quantization).
  2. Compress BMP image to candidate JPEG.
  3. Decompress candidate JPEG.
  4. Compare decompressed image with original BMP.
    • If the same, output the candidate JPEG and terminate.
    • If different, update the compression parameters and return to step 2.

The trick would be in that update step - figuring out how the image diffs could guide you to improve the parameters.

You might be able to write code that would work in the vast majority of cases. There are basically only 3 color sampling choices and my guess is there aren't that many algorithms to generate quantization matrices. You could implement them all, or alternatively scan the internet for JPEG files and record unique compression parameters. Then you would expect to fail primarily on images from newly written compressors.

It is important to note that these approaches depend on using the same decompressor for the => operations, as different decompressors may not produce the same image bit for bit from one JPEG file.

rhashimoto
  • 15,650
  • 2
  • 52
  • 80
1

Basically, we're dealing with image format and compression here. First, let's focus on the process which allows you to convert your JPEG image to BMP. BMP is formed with a map of pixels with R.G.B values. So, in term of visual aspect and in term of edges, you should not observe a difference between the original JPEG image and a conversion of this pic in BMP (resolution issues put apart).

On the contrary, as said by other contributors and here (http://en.wikipedia.org/wiki/JPEG), the JPEG format uses a compression matrix (DCT) that will somehow alter the gradient of your picture.

In most case, I would tend to say that it won't work, exception made of simplistic pictures (homogenous shape on uniform background color). It won't work on cam or video pics.

SIMA971
  • 31
  • 2