2
$\begingroup$

Forgive me if this is the wrong site for this question. Here's my problem: I am creating a game where players have to search for a hidden detail within the overall image. I downloaded an 11MB compressed photo from the internet which is 85MP in size (14000 x 6000 pixels). I had a very small image within this (a pixel-sized number). The color and brightness of this number closely matches the surrounding pixels so that it blends in. Now, when I went to save this image, the compression destroyed the hidden number, even at JPEG 12/Maximum. This maximum compressed JPEG increased the file size to 50MB even though the original was just 11MB. An uncompressed save file (TIF/PNG) reaches up to 250MB.

Is there anything I can do to compress the image while still preserving the integrity of the number? The number only encompasses a few pixels, but the addition of this small data has increased the file size 25x. I have access to Photoshop and Gimp. Thanks in advance, if you need to see the file then I can provide a link to it (at 250MB size or 50MB size).

$\endgroup$

2 Answers 2

4
$\begingroup$

To insert a JPEG image into another without recompression, you can use a jpegtran version with crop 'n' drop. It is safest to insert into coordinates that are multiples of the 16x16 pixel JPEG block size. On command line:

jpegtran.exe -drop +16+16 pixelated.jpg piano.jpg out.jpg

pixelated.jpgpixelated.jpg

piano.jpgpiano.jpg

out.jpgout.jpg

Difference images made in Gimp show only black, so there was no lossy recompression.

Difference image: piano.jpg vs. out.jpgDifference image: piano.jpg vs. out.jpg

Difference image: pixelated.jpg (aligned) vs. out.jpgDifference image: pixelated.jpg (aligned) vs. out.jpg

Before all this, you can use

jpegtran -crop 

to copy the target region in the big image to a file for modification.

I wonder if jpegtran can handle your huge files. My test files were quite small.

$\endgroup$
5
  • $\begingroup$ Okay, I think this is definitely on the right track. I downloaded/installed the software, now I need to do the drop. So the problem now is, how do I figure out where the correct coordinates for where to do the drop? I had an idea that by creating a new, blank (transparent) image with the same height/width of the old one, and placing the number on the new image in the correct location, the drop could work without needing the exact coordinates. JPG doesn't do transparency though. Will this still work? $\endgroup$ Commented Jul 13, 2015 at 17:35
  • $\begingroup$ Another problem. The image file I would be adding (with the number and nothing else) suffered the same compression problems caused me to write this up in the first place. Will the jpegtran program work if one image is a PNG/TIF and the other is a JPG? $\endgroup$ Commented Jul 13, 2015 at 18:04
  • $\begingroup$ 1. Jpegtran works because 16x16 pixel blocks are compressed independently of each other. It can't do transparency for you so you need another program to create the to-be-dropped image from the cropped image and the text image. 2. No, it needs to be a JPEG file. Try another to-JPEG converter. $\endgroup$ Commented Jul 13, 2015 at 18:11
  • $\begingroup$ Is there a tool that can do this on Mac or Linux? $\endgroup$ Commented Jul 21, 2022 at 20:08
  • $\begingroup$ @AaronFranke jpegtran seems to be available for Linux. See also linuxquestions.org/questions/linux-software-2/… $\endgroup$ Commented Jul 22, 2022 at 5:13
1
$\begingroup$

First of all, TIF/PNG is already compressed. But it is lossless compression. That means that your image should be unchanged but the price for complicated pictures is a higher memory footprint.

Rapid calculation:

(14000 * 6000 * 24 / 8) / (1024 * 1024) = 240 MB

(assuming 24-bit depth).

So it seems that your image is either pure random noise OR something went wrong and you did not get a proper PNG. Based on these data, I would first recommend to resize your image as such a size is simply insane for a point&click game.


Secondly, what you are asking cannot be trivially done the way you want it done. You said it yourself:

The color and brightness of this number closely matches the surrounding pixels so that it blends in.

JPEG is lossy and achieves such high compression ratios by removing the visual feature that are the hardest for the human eye to differentiate: similar colors, similar brightness, highly localized data, etc. It does so because that's what allows to keep the highest quality while increasing the compression ratio.

Now I think that you understand that what you are trying to keep is precisely what JPEG was designed to remove first.


There are a few ways to avoid that:

  • Use another codec.
  • "Blend" less so that the codec does not remove it.
  • Use tools like pngquant to achieve lossy compression in png, resize your original image, etc. to keep the size low and the quality up.
  • Change the type of image: do you really need photo-realistic pictures?
  • Change the way you make your program.
  • etc.

The "Change the way you make your program" part is the most sensible to me. You basically just use the original (preferably resized) image but before rendering it on screen, you add the information where you want it to be. This is far easier than tricking a compression algorithm into not doing its job and it's also a great win quality-wise and size-wise (you only need one copy of the original image, not X copies each containing your watermark).


Finally, if what you want is steganography, this is not a recommendable way to achieve it.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.