0

I'm testing different ways to store a jpg file in java and using a ByteArrayInputStream from a buffered image always results in a smaller file size. Is there anyway around this?

So for the whole picture, I'm currently trying to write a client-server image storing program(with eventual editing capabilities, think adobe lightroom). Uploading to the server from the client is no problem, just use Files.readAllBytes(currentFile.toPath()); and vice-versa when downloading to the client from the server, since it's being stored as a file.

The problem is what to do when I want to upload the same image I received(Assuming the image is edited and wanted to be reuploaded to server). I don't have a file created from it so I can't use the readAllBytes functions, they're only stored as an Image Object or BufferedImage. When I write that to a ByteArrayInputStream and get the size of the byte[] array to send back to the server, it's always smaller than the originals.

As a last resort I can make this into an export option so you have to download an image from the server onto the computer before editing, but it would make workflow less efficient.

currentFile = fileChooser.showOpenDialog(window);
            try{

            currentImage = new Image(currentFile.toURI().toString());
            SelectedImageView.setImage(currentImage);
            MainImageLayout.setLeft(SelectedImageView);


            System.out.println("Original file length "+currentFile.length());

                try {
                    BufferedImage bImage = ImageIO.read(currentFile);

                    byte[] fileContent = Files.readAllBytes(currentFile.toPath());
                    System.out.println("bytes from fileContent " +fileContent.length);

                    ByteArrayOutputStream tmp = new ByteArrayOutputStream();
                    ImageIO.write(bImage, "jpg", tmp);
                    tmp.flush();
                    byte[] imageBytes = tmp.toByteArray();
                    tmp.close();
                    long length = imageBytes.length;


                    System.out.println("length of bytearraystream " + length);

Printed Results:
Original file length 196874
bytes from fileContent 196874
length of bytearraystream 117010
Pawan Tiwari
  • 518
  • 6
  • 26
Tracer202
  • 1
  • 1
  • 2
    JPEG is a *lossy* format, meaning it sacrifices pixel-perfect image representation for better compression. A JPEG image can have greater compression, at the expense of image quality, or it can have poorer compression and better quality, at the expense of image size. Your call to `ImageIO.write` is creating a JPEG with a different compression level and therefore a different size. – VGR Apr 05 '19 at 05:36
  • @VGR Is there anyway to change the compression to quality ratio? If not, would 'png' be a better choice to preserve image quality? – Tracer202 Apr 05 '19 at 05:57
  • See https://stackoverflow.com/questions/17108234/setting-jpg-compression-level-with-imageio-in-java. PNG is a good choice in general, especially if you are reading image files which might not be JPEGs, since using a lossy format would mean that some pixels of the original image would be altered. – VGR Apr 05 '19 at 06:01
  • @VGR Thanks for the help, It'll take a while for me to understand compression differences but my first tests with PNG are looking better. Will check in tomorrow to see if this fixes my server problem. – Tracer202 Apr 05 '19 at 06:35

0 Answers0