PImage to Base64 for API upload

Hi All,

Based on this thread and some code from @snir102002 I have put a sketch together which encodes an image to Base64, decodes it and then displays it. This works as expected.

However, when I send the Base64 string to my API I get a response telling me that my string isn't valid. For troubleshooting I've saved the string in a txt file, copied it and pasted in a an Base64 online decoder but none of them seem to be able to interpret it.

Where am I going wrong?

Here's an executable code:

import org.apache.commons.codec.binary.Base64;
import java.io.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

void setup() {
  size(1200, 600);
  PImage img = loadImage("http" + "://i.stack.imgur.com/WCveg.jpg");
  image(img, 0, 0);

  String encoded = "";
  PImage decoded = createImage(img.width, img.height, RGB);

  try {
    encoded = EncodePImageToBase64(img);
    //println(encoded);
  } 
  catch (IOException e) {
    println(e);
  }
  String [] hell = {encoded};

  saveStrings("encoded.txt", hell);

  try {
    decoded = DecodePImageFromBase64(encoded);
    println(decoded);
  } 
  catch (IOException e) {
    println(e);
  }

  image(decoded, img.width, 0);
}



public String EncodePImageToBase64(PImage i_Image) throws UnsupportedEncodingException, IOException
{
  String result = null;
  BufferedImage buffImage = (BufferedImage)i_Image.getNative();
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  ImageIO.write(buffImage, "PNG", out);
  byte[] bytes = out.toByteArray();
  result = Base64.encodeBase64URLSafeString(bytes);

  return result;
}


public PImage DecodePImageFromBase64(String i_Image64) throws IOException
{
  PImage result = null;
  byte[] decodedBytes = Base64.decodeBase64(i_Image64);

  ByteArrayInputStream in = new ByteArrayInputStream(decodedBytes);
  BufferedImage bImageFromConvert = ImageIO.read(in);
  BufferedImage convertedImg = new BufferedImage(bImageFromConvert.getWidth(), bImageFromConvert.getHeight(), BufferedImage.TYPE_INT_ARGB);
  convertedImg.getGraphics().drawImage(bImageFromConvert, 0, 0, null);
  result = new PImage(convertedImg);

  return result;
}

Answers

  • edited May 2017 Answer ✓

    Here's a working implementation :D

    import org.apache.commons.codec.binary.Base64;
    import java.io.*;
    import java.awt.image.BufferedImage;
    import javax.imageio.ImageIO;
    
    void setup() {
      size(1200, 600);
    
      String encoded = "";
      PImage decoded = createImage(500, 500, RGB);
    
      String fileLocation = "C:/Users/charles.fried/Documents/Window/FaceRecogntion/Face++/Faces/Charles/Snapshot_20170511.jpg";
    
      try {
        encoded = encodeToBase64(fileLocation);
      } 
      catch (IOException e) {
        e.printStackTrace();
      }
    
      try {
        decoded = DecodePImageFromBase64(encoded);
      } 
      catch (IOException e) {
        println(e);
      }
    
      image(decoded, 0, 0);
    
      String [] arrayForSave = {encoded};
      saveStrings("encoded.txt", arrayForSave);
    }
    
    private String encodeToBase64(String fileLoc) throws IOException, FileNotFoundException {
    
      File originalFile = new File(fileLoc);
      String encodedBase64 = null;
    
      FileInputStream fileInputStreamReader = new FileInputStream(originalFile);
      byte[] bytes = new byte[(int)originalFile.length()];
      fileInputStreamReader.read(bytes);
      encodedBase64 = new String(Base64.encodeBase64(bytes));
      fileInputStreamReader.close();
    
      return encodedBase64;
    }
    
    public PImage DecodePImageFromBase64(String i_Image64) throws IOException
    {
      PImage result = null;
      byte[] decodedBytes = Base64.decodeBase64(i_Image64);
    
      ByteArrayInputStream in = new ByteArrayInputStream(decodedBytes);
      BufferedImage bImageFromConvert = ImageIO.read(in);
      BufferedImage convertedImg = new BufferedImage(bImageFromConvert.getWidth(), bImageFromConvert.getHeight(), BufferedImage.TYPE_INT_ARGB);
      convertedImg.getGraphics().drawImage(bImageFromConvert, 0, 0, null);
      result = new PImage(convertedImg);
    
      return result;
    }
    
  • Neat! Thanks for sharing \m/ :bz

    Kf

  • edited May 2017

    Excellent. Thanks for sharing this, @CharlesDesign.

    Note that an equally valid option to apache's Base64 is to use Java 8 import java.util.Base64. Then instead of Base64.encodeBase64() you use Base64.getEncoder().encode().

    So either:

    import org.apache.commons.codec.binary.Base64;
    byte[] encodedBytes = Base64.encodeBase64("Test".getBytes());
    System.out.println("encodedBytes " + new String(encodedBytes));
    byte[] decodedBytes = Base64.decodeBase64(encodedBytes);
    System.out.println("decodedBytes " + new String(decodedBytes));
    

    or:

    import java.util.Base64;
    byte[] encodedBytes = Base64.getEncoder().encode("Test".getBytes());
    System.out.println("encodedBytes " + new String(encodedBytes));
    byte[] decodedBytes = Base64.getDecoder().decode(encodedBytes);
    System.out.println("decodedBytes " + new String(decodedBytes));
    

    For discussion see: http://stackoverflow.com/a/13109632/7207622

Sign In or Register to comment.