[Java] Anything-To-PNG File Converter

Accname

2D-Graphics enthusiast
Reaction score
1,462
Hi there.

I was having a crazy idea recently. I was thinking how safe it would be to share files with each other over the internet by using the PNG-file format for encryption.
If I take a piece of music, or a video, or software, or anything; and, instead of uploading it somewhere as is, I encrypt it and transform it into an image, then upload it as an image to some image hosting service.
Somebody else can then download this image easily, run it through a decryption program, and have it restored 1 to 1.

There are several benefits to this. First of all you can upload any file type to a simple image hosting service. You can easily split the file into different parts with imaging software and somebody else can just put them back together.
Its hard to decrypt the file without knowing what kind of file it originally was.
You can also add a generated random key for extra protection.
And, file size is reduced by using the standard PNG compression methods.

I have actually already written an encryption algorithm which can turn any file into a png.
However, I have problems loading the file again. Maybe somebody here knows why, and this is why I am posting this.
The problem is that a few bytes will be returned as -1 although I am very sure I didnt put -1 in there.

Here is my encryption code:
Code:
    public static void encrypt(File file) throws IOException {
        /*
         * Read the file byte by byte and store the information in a list.
         */
        DataInputStream is = new DataInputStream(new FileInputStream(file));
        ArrayList<Byte> data = new ArrayList<>();
        try {
            while (true) {
                data.add(is.readByte());
            }
        } catch (EOFException eof) {
        }
        is.close();
        
        /*
         * Calculations for various important variables.
         */
        int sizeInBytes = data.size();
        System.out.println("Size in bytes "+sizeInBytes);
        
        int sizeInPixels = sizeInBytes / BYTES_PER_PIXEL;
        System.out.println("Size in pixels "+sizeInPixels);
        
        int imgWidth = (int) Math.ceil(Math.sqrt(sizeInPixels + 4));
        System.out.println("Image width "+imgWidth);
        
        int imgHeight = (int) Math.ceil((sizeInPixels + 4) * 1f / imgWidth);
        System.out.println("Image height "+imgHeight);
        
        int imgTotalPixels = imgWidth * imgHeight;
        System.out.println("Image total pixels "+imgTotalPixels);
        
        int imgTotalBytes = imgTotalPixels * BYTES_PER_PIXEL;
        System.out.println("Image total bytes "+imgTotalBytes);
        
        /*
         * Create buffer to store 
         */
        byte[] pixels = new byte[imgTotalBytes];
        // Store the size of the file in the first 4 bytes:
        pixels[0] = (byte) (sizeInBytes >> 0);
        pixels[1] = (byte) (sizeInBytes >> 8);
        pixels[2] = (byte) (sizeInBytes >> 16);
        pixels[3] = (byte) (sizeInBytes >> 24);
        // Store the rest of the file as is:
        for (int i = 0; i < data.size(); i++) {
            if (i % 4 == 0) {
                System.out.println();
            }
            if (pixels[i] >= 0) {
                System.out.print(' ');
            }
            if (pixels[i] / 100 == 0) {
                System.out.print(' ');
            }
            if (pixels[i] / 10 == 0) {
                System.out.print(' ');
            }
            System.out.print(pixels[i]);
            System.out.print(", ");
            
            pixels[4 + i] = data.get(i);
        }
        
        /*
         * Save the file as a compressed png.
         */
        PNGEncoder.save(file.getAbsolutePath()+".png", pixels, imgWidth, imgHeight, Filter.NONE, Compression.LEVEL_9);
        System.out.println("finished");
    }
This works very well so far.

Now here is the code for loading the image and converting it back:
Code:
    public static void decrypt(File file) throws IOException {
        /*
         * Load the file and decode it.
         */
        InputStream stream = new FileInputStream(file);
        PNGDecoder decoder = new PNGDecoder(stream);
        
        int width = decoder.getWidth();
        int height = decoder.getHeight();
        System.out.println("Image size "+width+" x "+height);
        
        ByteBuffer buffer = ByteBuffer.allocate(width * height * 4).order(ByteOrder.LITTLE_ENDIAN);
        decoder.decode(buffer, decoder.getWidth() * 4, PNGDecoder.Format.RGBA);
        stream.close();
        buffer.clear();
        
        /*
         * Load the size of the original file from the first 4 bytes.
         */
        byte[] sizeInBytesArray = new byte[] {
            buffer.get(),
            buffer.get(),
            buffer.get(),
            buffer.get()
        };
        System.out.println("First 4 bytes "+sizeInBytesArray[0]+", "+sizeInBytesArray[1]+", "+sizeInBytesArray[2]+", "+sizeInBytesArray[3]);
        
        int sizeInBytes = ((sizeInBytesArray[3] & 0xFF) << 24) | ((sizeInBytesArray[2] & 0xFF) << 16)
                | ((sizeInBytesArray[1] & 0xFF) << 8) | (sizeInBytesArray[0] & 0xFF);
        System.out.println("Size in bytes "+sizeInBytes);
        System.out.println("Buffer.remaining = "+buffer.remaining());
        
        /*
         * Write the file to disk and output the contents.
         */
        DataOutputStream out = new DataOutputStream(new FileOutputStream(file.getAbsolutePath()+".zip"));
        for (int i = 0; i < sizeInBytes; i++) {
            if (i % 4 == 0) {
                System.out.println();
            }
            byte b = buffer.get();
            if (b >= 0) {
                System.out.print(' ');
            }
            if (b / 100 == 0) {
                System.out.print(' ');
            }
            if (b / 10 == 0) {
                System.out.print(' ');
            }
            System.out.print(b);
            System.out.print(", ");
            out.write(b);
        }
        out.close();
        System.out.println("finished");
    }
These are some example outputs I got:
Encryption:
Code:
-118,    0,    0,    0,
  80,  75,    3,    4,
  20,    0,    2,    0,
  8,    0,  102, -109,
116,  67,  30,  -35,
  77,  70,  14,    0,
  0,    0,  34,    0,
  0,    0,  13,    0,
  0,    0,  84,  101,
115,  116,  45,  84,
101,  120,  116,  46,
116,  120,  116,  11,
  73,  45,  46,  81,
  40,  65,  33, -112,
-111,  -98,  -98,  30,
  0,  80,  75,    1,
  2,  20,    0,  20,
  0,    2,    0,    8,
  0,  102, -109,  116,
  67,  30,  -35,  77,
  70,  14,    0,    0,
  0,  34,    0,    0,
  0,  13,    0,    0,
  0,    0,    0,    0,
  0,    1,    0,  32,
  0,    0,    0,    0,
  0,    0,    0,  84,
101,  115,  116,  45,
  84,  101,  120,  116,
  46,  116,  120,  116,
  80,  75,    5,    6,
  0,    0,    0,    0,
  1,    0,    1,    0,
  59,    0,    0,    0,
  57,    0,    0,    0,
  0,    0,    0,    0,
  0,    0,    0,    0,
  0,    0,    0,    0,
  0,    0,    0,    0,
  0,    0,    0,    0,
  0,    0,    0,    0,
  0,    0,    0,    0,
  0,    0,    0,    0,
  0,    0,    0,    0,
  0,    0,    0,    0,
  0,    0,    0,    0,
  0,    0,    0,    0,
  0,    0,    0,    0,
  0,    0,    0,    0,

Decryption:
Code:
-118,    0,    0,  -1,
  -1,  80,  75,    3,
  4,  20,    0,    2,
  0,    8,    0,  102,
-109,  116,  67,  30,
-35,  77,  70,  14,
  0,    0,    0,  34,
  0,    0,    0,  13,
  0,    0,    0,  84,
101,  115,  116,  45,
  84,  101,  120,  116,
  46,  116,  120,  116,
  11,  73,  45,  46,
  81,  40,  65,  33,
-112,  -1,  -1,  -98,
  -1,    0,  80,  75,
  1,    2,  20,    0,
  20,    0,    2,    0,
  8,  -1,  -1, -109,
  -1,  -1,  -1,  -35,
  -1,  70,  14,    0,
  0,    0,  34,    0,
  0,    0,  13,    0,
  0,    0,    0,    0,
  0,    0,    1,    0,
  32,    0,    0,    0,
  0,    0,    0,    0,
  84,  101,  115,  116,
  45,  84,  101,  120,
116,  46,  116,  120,
116,  80,  75,    5,
  6,    0,    0,    0,
  0,    1,    0,    1,
  0,  59,    0,    0,
  0,  57,    0,    0,
  0,    0,

I would guess this has to do with the way PNG's are stored, but I am not 100% sure.
By the way, without the png compression I get the very same results. The encoders and decoders work flawlessly. I already tested these.

Thank you a bunch.
 

monoVertex

I'm back!
Reaction score
460
I don't really have the time to look at the code now, but I have a question:

How exactly is this different from .zip files and archives in general? :p I mean, you have the same encode / decode process, you can upload .zip files pretty much everywhere (so the other person still needs to actually download and decode the file), you can split them easily into smaller parts, without needing an image editor, you have password protection (which, depending on the program you use, can achieve this through an unbreakable algorithm - talking about 7-zip for Windows).

The archive format also obfuscates the file contents and besides this, you can archive multiple files at once, as opposed to having to run the encoder / decoder on single files.

I am also pretty sure that the algorithms used in archive compression achieve pretty good results (in 7-zip you can configure that and an archive created with maximum compression is really small compared to original file size; it only takes longer to zip / unzip).
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
I know for a fact, that the compression of png files is pretty powerful.
I encrypted an MP3 which was 3.6mb of data.
As a .zip file with best compression I got 3.4mb. (Not a very impressive result)
As a png I got 2.15mb.


But thats not the point. I never made this program for any real purpose other then that I was bored.
I just wanted to see if I could do it. There is no real advantage of using it besides the joy of seeing your files being converted to .png's.
 

monoVertex

I'm back!
Reaction score
460
Wow, that's interesting. What did you zip it with? As I said, it depends a lot on the program you use.

I was thinking that you wanted to promote it as an actual compression method and I think that would encounter a lot of resistance, because of how widespread the archive files already are.

However, I am really interested in the finished product, because I think it might spawn a new artistic technique. I'm guessing the PNG results are actually view-able as images and I think some interesting effects might come up, depending on what you encode :D.
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
Yeah, its viewable. Doesnt look good or anything, its just pixel garbage, but its viewable.

I used WinRar to zip the file. And probably a very old version of WinRar. I didnt really care much about it.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top