ChonBonStudios
ChonBonStudios

Reputation: 223

Java : Writing a String to a JPG File

Alright, so I am writing a small program that should have taken 10 minutes to complete however I am running into unforeseen problems.

The program should take in some old files I had in a vault program on my old phone, they are basically Jpg files but with an added "obscured" text to the front of the file.

So below is my code logic

  1. get a folder input for the files,
  2. create an arraylist containing each actual file.
  3. call ConvertFiles to convert the file to a string,
  4. delete the first 8 characters using substring and save that temp file to another arraylist containing the strings.
  5. decode that string as base64 and input that into a bytearrayinputstream and save that to a bufferedimage.

This is where the problem occurs. I have content all the way up to the ImageIO.read(bis), so when it tries to write to a new file it throws the image == null from the ImageTypeSpecifier. I have tried multiple ways of decoding and encoding the string, but any help is wanted and if any more information is needed I will provide it!

public class ImageConvert {

    private File folder;
    private ArrayList<File> files;
    private ArrayList<String> stringFiles = new ArrayList<>();
    private ArrayList<BufferedImage> bfImages = new ArrayList<>();
    boolean isRunning = true;
    Scanner scanner = new Scanner(System.in);
    String folderPath;

    public static void main(String[] args) {
        ImageConvert mc = new ImageConvert();
        mc.mainCode();
    }

    public void mainCode(){
        System.out.println("Please enter the folder path: ");
        folderPath = scanner.nextLine();
        folder = new File(folderPath);
        //System.out.println("folderpath: " + folder);
        files = new ArrayList<File>(Arrays.asList(folder.listFiles()));
        convertFiles();
    }

    public void convertFiles(){
        for(int i = 0; i < files.size(); i++){
            try {
                String temp = FileUtils.readFileToString(files.get(i));
                //System.out.println("String " + i + " : " + temp);
                stringFiles.add(temp.substring(8));
            } catch (IOException ex) {
                Logger.getLogger(ImageConvert.class.getName()).log(Level.SEVERE,
                                                                    null, ex);
            }
        }

        //System.out.println("Converted string 1: " + stringFiles.get(0));
        for(int j = 0; j < stringFiles.size(); j++){

            BufferedImage image = null;
            byte[] imageByte;

            try {
               BASE64Decoder decoder = new BASE64Decoder();
               imageByte = decoder.decodeBuffer(stringFiles.get(j));
               System.out.println(imageByte.toString());
               ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
               image = ImageIO.read(bis);
               bis.close();
               bfImages.add(image);
          } catch (IOException ex) {
               Logger.getLogger(ImageConvert.class.getName()).log(Level.SEVERE,
                                                                   null, ex);
          }

        }


        System.out.println("Image 1: " + bfImages.get(0));

        for(int k = 0; k < bfImages.size(); k++){
            try {
                ImageIO.write(bfImages.get(k), "jpg",
                              new File(folderPath + "/" + k + ".jpg"));
            } catch (IOException ex) {
                Logger.getLogger(ImageConvert.class.getName()).log(Level.SEVERE,
                                                                    null, ex);
            }
        }

    }

}

This is an example of my files:

Upvotes: 2

Views: 3308

Answers (1)

Jonny Henly
Jonny Henly

Reputation: 4213

The following example uses the file you included with your question. You don't need to do any decoding, just read the file into memory, store the 8 byte String and then write the remaining bytes to a jpg from an 8 byte offset.

Just adapt the method below to work with your: "folder input for files". You don't need an ArrayList containing each actual jpg file.

public void convertFiles() {
    File imgFile;
    byte[] bytes;
    FileOutputStream fos;
    String temp;

    for (int i = 0; i < files.size(); i++) {
        temp = "";

        try {
            // 'read' method can be found below
            bytes = read(files.get(i));

            // read the 8 byte string from the beginning of the file
            for(int j = 0; j < 8; j++) {
                temp += (char) bytes[j];
            }

            imgFile = new File("img.jpg");

            // points to './img.jpg'
            fos = new FileOutputStream(imgFile);

            // write from offset 8 to end of 'bytes'
            fos.write(bytes, 8, bytes.length - 8);

            fos.close();
        } catch (FileNotFoundException e) {
            // Logger stuff
        } catch (IOException ex) {
            // Logger stuff
        }

        System.out.println("[temp]:> " + temp);
    }

}

read(File file) method adapted from a community wiki answer to File to byte[] in Java

public byte[] read(File file) throws IOException {
    ByteArrayOutputStream ous = null;
    InputStream ios = null;
    try {
        byte[] buffer = new byte[4096];
        ous = new ByteArrayOutputStream();
        ios = new FileInputStream(file);
        int read = 0;
        while ((read = ios.read(buffer)) != -1) {
            ous.write(buffer, 0, read);
        }
    } finally {
        try {
            if (ous != null)
                ous.close();
        } catch (IOException e) {
        }

        try {
            if (ios != null)
                ios.close();
        } catch (IOException e) {
        }
    }

    return ous.toByteArray();
}

Output:

[temp]:> obscured

Image File:

Decoded image file.

Upvotes: 2

Related Questions