Java LZW Compresss & Decompress with Image - java

I've checked many sources about LZW compression but it didn't work with image file.
Here are the resources what I have checked so far:
https://www.codemiles.com/java/lzw-data-compression-decompression-algorithm-java-code-t99.html
This one the compress file is bigger than original file
https://codereview.stackexchange.com/questions/122080/simplifying-lzw-compression-decompression
Could you please give any resource that work with image compression?
Thanks!!!

Compressing an already compressed image is not a good idea, because the first compression removes any statistical hints the second compressor can use. That's at least true for contemporary compression algorithms, like they are used in the JPEG, PNG, GIF, TIFF, and WebP image formats. Typically, a compressed file, viewed in a hex editor, looks quite like a stream of random bytes, and random data (or non-random data with statistical properties similar to random data) cannot be compressed. Usually the result is even bigger than the original, due to some overhead in the storage format. Clever compressors detect this condition and revert to simply storing the original data, rather than compressing it.
So if you think that your image might be compressed further, you'll have to decompress it first. Then you can try a different compressor that might yield better results. However, I doubt that any LZW variant will give you any significant gain over JPEG. While it's a really clever enhancement of the Lempel-Ziv family of compression algorithms, LZW is a purely lossless technique, and hence has some innate limitation of the attainable compression ratio, rooted in the statistical distribution of the image data. JPEG and other lossy image formats trade image quality for size, and thus can easily outperform lossless techniques.
Note that the GIF format is a special case. While it uses lossless LZW compression, it requires a color palette of up to 256 entries. To encode a colorful image like a photograph as GIF, you'll have to quantize the color space first to get a 256-color palette. This is once again a lossy technique, albeit quite different from the algorithms used by JPEG and WebP lossy. Quantized GIF images of photos compress excellently due to the reduction of RGB information in the image, but expose noticeable deteriorations of color gradients, like they are found in human faces, flower leaves, and a cloudy heaven.
As an aside: If GIF would allow larger color palettes (say, 1024), it might become a real killer format for photographic images. Maybe it's time for a GIF17a format update?!

Related

How to reduce the size of split PDF document in PDFBox? [duplicate]

I have a PDF file to save, but first I have to compress it with the best possible quality and I must use open source library (like Apache PDFBox®).
So, until now what I do is get all the image type resources, compress them and put them back in the PDF, but the compression ratio is to low. This is just a fragment of the code where I assign the compression parameters:
PDImageXObject imageXObject = (PDImageXObject) pdxObject;
ImageWriter imageWriter = ImageIO
.getImageWritersByFormatName(FileType.JPEG.name().toLowerCase()).next();
ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
imageWriteParam.setCompressionQuality(COMPRESSION_FACTOR);
There is some other mechanism to optimize a PDF, so far only compress the images shows a slightly poor result.
On compression. Indeed, images probably are the largest culprits.
Images: The image size, width and height, contribute to the file size too, not only the lossy image quality (your COMPRESSION_FACTOR). In general I would start with compressing a JPEG file outside the PDF. Then you can find the best compression, that still shows and prints (!) adequately. Photos JPEG, vector graphics (like diagrams) can best be done with Encapsulated PostScript.
Repeated images like page logos should not be stored repeatedly. The optimisation here is internet streaming.
Fonts: The default fonts need no space, the full fonts need the most space (for PDFs with forms for instance). Embedded fonts are a third possibility, only loading the symbols one needs.
PDFs own binary data: Text and other parts can be uncompressed, compressed using only 7bits ASCII, and further compressed using all bytes. The ASCII option is a bit outdated.
At the moment I am not using pdfbox, hence I leave that to you.

What is the best solution to compress PDF with PDFBox?

I have a PDF file to save, but first I have to compress it with the best possible quality and I must use open source library (like Apache PDFBox®).
So, until now what I do is get all the image type resources, compress them and put them back in the PDF, but the compression ratio is to low. This is just a fragment of the code where I assign the compression parameters:
PDImageXObject imageXObject = (PDImageXObject) pdxObject;
ImageWriter imageWriter = ImageIO
.getImageWritersByFormatName(FileType.JPEG.name().toLowerCase()).next();
ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
imageWriteParam.setCompressionQuality(COMPRESSION_FACTOR);
There is some other mechanism to optimize a PDF, so far only compress the images shows a slightly poor result.
On compression. Indeed, images probably are the largest culprits.
Images: The image size, width and height, contribute to the file size too, not only the lossy image quality (your COMPRESSION_FACTOR). In general I would start with compressing a JPEG file outside the PDF. Then you can find the best compression, that still shows and prints (!) adequately. Photos JPEG, vector graphics (like diagrams) can best be done with Encapsulated PostScript.
Repeated images like page logos should not be stored repeatedly. The optimisation here is internet streaming.
Fonts: The default fonts need no space, the full fonts need the most space (for PDFs with forms for instance). Embedded fonts are a third possibility, only loading the symbols one needs.
PDFs own binary data: Text and other parts can be uncompressed, compressed using only 7bits ASCII, and further compressed using all bytes. The ASCII option is a bit outdated.
At the moment I am not using pdfbox, hence I leave that to you.

Image size increased twice when convert from JPG to PNG using thumbnailator

Am using Thumbnailator to compress the image in my application. Everything is work fine alone when i try to convert the JPG image to PNG. At this process the size of an image getting twice after compressing. Following code is am used to convert image.
File a=new File("C:\\Users\\muthu\\Downloads\\SampleJPGImage_5mbmb.jpg");
Thumbnails.of(a).scale(1).outputQuality(0.5).toFile("C:\\Users\\muthu\\Downloads\\SampleJPGImage_5mbmb1.png");
using pure java also doing same and code is follows
BufferedImage bufferedImage = ImageIO.read(new File("C:\\Users\\muthu\\Downloads\\SampleJPGImage_5mbmb.jpg"));
ImageIO.write(bufferedImage, "png", new File("C:\\Users\\muthu\\Downloads\\javaPngimage.png"));
Ex: 5MB image file is converted to 32MB file. I should not go for resize to compress. Am stuck with this
JPEG and PNG are both compressed image formats.
JPEG compresses the pixels using frequency transforms and quantisation. It can be a lossy or lossless compression format.
PNG is a lossless compression format with different compression mechanisms. I dare say the "quality" parameter doesn’t actually change the image at all.
The biggest image file type would be BMP (.bmp), which is 3 bytes (RGB) for each pixel plus a header. It’s worth keeping this size in mind when deciding if an image file is "big" or not. JPEG compression is pretty good.
It sounds like your image has a lot of details that can be compressed well in the frequency domain (JPEG) but compress poorly as PNG.
Simplest solution: a JPEG format thumbnail. If you needed to use PNG, and you were resizing your image, I’d suggest resize JPEG then convert to PNG.

How to create a new image format?

I have been playing around with some image processing tools in java and was wondering how to create my own image format (with its own file extension and header).
Say I am trying to store 2 jpeg images into a new file with extension .abcde
How would I approach this and modify the file header?
I did some research and found this, but it didnt have any sort of example.
https://gamedevelopment.tutsplus.com/tutorials/create-custom-binary-file-formats-for-your-games-data--gamedev-206
Any advice/references/examples would be great, thanks.
Okay. Here you should ask yourself a question — what is binary file? It is some type of "box" that contains 8-bit values (0-255 range). And what actually images are? The same. But data in images is stored specifically. If you look at bitmaps (*.BMP files) for example, you'll see that it contains RGB values (it actually depends on the color depth, but we are talking about 24-bit colors now). So, what does it mean? It means that each pixel is stored with 3 bytes (24 bits) for Red Green and Blue values.
EG: 0x00 0x00 0x00 — This is black pixel in hex representation
0xFF 0xFF 0xFF — White.
But storing image data in such way is quite inefficient. For example, 1024x1024 image would be 1024*1024*3=3145728 bytes!! Or 3 MEGABYTES. And that is not including alpha channel, which also stored with one byte.
So, here the data compression comes in, it can be lossy or lossless. If you open for example a PNG file in the hex editor, you'll see a DEFLATE compressed data (LZ77+Huffman coding). It is lossless.
GIF files are compressed with LZW, which is quite inefficient nowadays. There lots of really nice image formats such as FLIF or BPG, which compress images better than PNG and JPEG.
So, if you want to create your own file format, you can create just a raw pixel container file (like BMP or PCX), or compressed pixel file (here you should write a custom data compression algorithm, C or C++ suits the best for this purpose).

java jpg pixel editing

I had a question concerning jpg image creation ImageIO.write(imgStega, "jpeg", file) :
I am doing some steganography, and I have to hide data in least significant bit of each pixel. I do this with getRGBA()[pos], which provide me Red, Blue, Green, Alpha components. Then I change each value with a +1 or -1 depending on a %2.
The problem is, every time I use ImageIO.write, it changes all my image at random (it is compressing). So, how can I save my image as it is ? I don't see any solution to do steganography on a real image.
Whether I use png or jpg is the same, the weight changes. Do you know a way to save my image the way it is ?
Thanks in advance !
JPEG is lossy by definition, so the data modifications that you see are expected and there is not much you can do about it in your context.
On the other hand, PNG is also compressed but in a lossless manner. The size of the png file changes because the png compression is similar to regular file compression (called LZ): very grossly explained, it detects repeated byte patterns and encodes them in fewer bytes. Changing the bytes of your image changes these patterns, and this may change the efficiency of the compression. You could as well see an increase in size. But when an application opens your modified image, it should see exactly the bytes that you have stored.
Is the change of size a concern because this might allow someone to detect your modifications? In that case, I don't see any other solution than using only uncompressed formats.

Categories

Resources