In this article I will provide you an approach to manipulate an image file. This article gives you an insight into some tricks in java so that you can conceal sensitive information inside an image, hide your complete image as text ,search for a particular image inside a directory, minimize the size of the image. However this is not a new concept, there is a concept called Steganography which enables to conceal your secret information inside an image. For this concept many very sophisticated softwares are available to manipulate the images. But as a java developer we can also
achieve it to an extent.
Normally many people keep all the personal images in a particular directory and others view the images by searching as *.jpg .
It hampers the privacy of your photos and images. In this article I will show you how you can convert your pictures, photos and images into text file to increase more privacy. Others can view your text file but can not understand what it is. There are occasions many users put all their secret and sesitive information like several bank details, credit card numbers ,email password details etc in a text file so that they can login specific applications easily. But it creates a problem when other others use the systems where these information are there . In this article I will show you how you can hide your personal details inside an image and you can retrieve the details as and when required. Let us go into the techincal details as I do not want to prolong my description.
Technicalities
It is very easy in Java to read an image and you can store the image contents as flat file. To achieve this, read the image file using ImageIO class in Java and convert the array of bytes into String using Base64Encoder . Here your major work is over, now you have manipulate the String in any manners. Let us have look into the cases.
Case – 1 : Hide you photos as text files
In this case you can hide all your photos or images into text files and rename the files in a such manner that other users will consider as system files or logs. In my class “ImageAnalyzerUtil”, there is a method which will convert an image into text file. The method name is “convertImageToText()”. In this method the image file is read as String using “Base64Encoder” and finally it written into a text file.
Case – 2 : Get back your original image from the text file
In the class “ImageAnalyzerUtil” there is a method called “convertTextToImage()” which will convert the text file into image. However all the text files will not be converted into images. Only those text files which have been converted from image files will create the image. In this case the converted text file is read and converted into array of byte using “Base64Decoder” and finally the array of bytes is written into file.
Case – 3 : Hide your sensitive information inside an image
In this case there is a method called “hideTextDataInsideImage()” in the class “ImageAnalyzerUtil”. Here an extra string is added to the image file with the other data so that data can be retrieved easily.
Case – 4 : Retrieve your sesitive information from an image
For this purpose there is a method called “getHiddenDataFromImage()” in the class “ImageAnalyzerUtil”. In this case the entire image is read as String and the sensitive information is separated and displayed.
Case – 5 : Minimize the image size
While working on this program, I found that while reverting the original image from the text file, the size of the image is reduced. There is no loss of image data but there may be a loss of some extra data which OS provides.
The complete program is given below with all revelent testharness program.
Expand|Select|Wrap|Line Numbers
- package com.ddsoft.tornado.core.image;
- import java.awt.image.BufferedImage;
- import java.io.BufferedOutputStream;
- import java.io.BufferedReader;
- import java.io.ByteArrayOutputStream;
- import java.io.DataInputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.io.OutputStreamWriter;
- import javax.imageio.ImageIO;
- /**
- * This class contains the following utility methods.
- * <p>
- * <li> Utility Method to read converted image text file </li>
- * <li> Utility method to write the image as text file </li>
- * <li> Utility method to get the image contents as String </li>
- * <li> Utility method hide the text data inside an image </li>
- * <li> Utility method get the hidden data from an image </li>
- * <li> Utility method to search a particular image inside a directory </li>
- * <li> Utility method to search and to obtain the full path of an image </li>
- * <li> Utility method to convert an image into a text file </li>
- * <li> Utility method to convert a text back into image </li>
- * @author Debadatta Mishra(PIKU)
- *
- */
- public class ImageAnalyzerUtil
- {
- /**
- * String type constant to define the image type.
- */
- private static String IMAGE_TYPE = "jpg";
- /**
- * An extra String that separates the image data and the secret information data
- */
- private static String extraStr = "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@";
- /**
- * This method is used to read the contents of a text( converted from image ) file
- * and provides byte[].
- * @param imageTextFilePath of type String indicating the path of the text file
- * @return an array of bytes
- * @author Debadatta Mishra(PIKU)
- */
- public static byte[] readImageTextFile( String imageTextFilePath )
- {
- byte[] dataFile = null;
- try
- {
- StringBuffer textData = new StringBuffer();
- FileInputStream fstream = new FileInputStream(imageTextFilePath);
- DataInputStream in = new DataInputStream(fstream);
- BufferedReader br = new BufferedReader(new InputStreamReader(in));
- String srtData;
- while ((srtData = br.readLine()) != null) {
- textData.append(srtData);
- }
- br.close();
- fstream.close();
- in.close();
- dataFile = new sun.misc.BASE64Decoder().decodeBuffer(textData.toString());
- }
- catch( Exception e )
- {
- e.printStackTrace();
- }
- return dataFile;
- }
- /**
- * This method is used to write the contents of an image into a text file.
- * @param filePath of type String indicating the path of the text file
- * @param imageContents of type String indicating the image contents as String
- * @author Debadatta Mishra(PIKU)
- */
- public static void writeImageAsTextFile( String filePath , String imageContents )
- {
- FileOutputStream fout=null;
- OutputStreamWriter osw = null;
- OutputStream bout = null;
- try
- {
- fout = new FileOutputStream (filePath);
- bout= new BufferedOutputStream(fout);
- osw = new OutputStreamWriter(bout, "utf-8");
- osw.write(imageContents);
- bout.close();
- osw.close();
- fout.close();
- }
- catch( Exception e )
- {
- e.printStackTrace();
- }
- }
- /**
- * This method is used to get the image contents as String.
- * @param imagePath of type String indicating the path of image file
- * @return a String of image contents
- * @author Debadatta Mishra(PIKU)
- */
- public static String getImageAsString( String imagePath )
- {
- String imageString = null;
- try
- {
- File f = new File(imagePath);
- BufferedImage buffImage = ImageIO.read(f);
- ByteArrayOutputStream os= new ByteArrayOutputStream();
- ImageIO.write(buffImage, IMAGE_TYPE, os);
- byte[] data= os.toByteArray();
- imageString = new sun.misc.BASE64Encoder().encode(data);
- }
- catch( FileNotFoundException fnfe )
- {
- fnfe.printStackTrace();
- System.out.println("Image is not located in the proper path.");
- }
- catch (IOException e)
- {
- e.printStackTrace();
- System.out.println("Error in reading the image.");
- }
- return imageString;
- }
- /**
- * This method is used to hide the data contents inside the image.
- * @param srcImagePath of type String indicating the path of the source image
- * @param dataContents of type String containing data
- * @author Debadatta Mishra(PIKU)
- */
- public static void hideTextDataInsideImage( String srcImagePath , String dataContents )
- {
- try
- {
- dataContents = new sun.misc.BASE64Encoder().encode(dataContents.getBytes());
- extraStr = new sun.misc.BASE64Encoder().encode(extraStr.getBytes());
- FileOutputStream fos = new FileOutputStream( srcImagePath , true );
- fos.write(new sun.misc.BASE64Decoder().decodeBuffer(extraStr.toString()));
- fos.write( dataContents.getBytes() );
- fos.close();
- }
- catch( FileNotFoundException fnfe )
- {
- fnfe.printStackTrace();
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- catch( Exception e )
- {
- e.printStackTrace();
- }
- }
- /**
- * This method is used to get the hidden data from an image.
- * @param imagePath of type String indicating the path of the image
- * which contains the hidden data
- * @return the String containing hidden data inside an image
- * @author Debadatta Mishra(PIKU)
- */
- public static String getHiddenDataFromImage( String imagePath )
- {
- String dataContents = null;
- try
- {
- File file = new File( imagePath );
- byte[] fileData = new byte[ (int)file.length()];
- InputStream inStream = new FileInputStream( file );
- inStream.read(fileData);
- inStream.close();
- String tempFileData = new String(fileData);
- String finalData = tempFileData.substring(tempFileData
- .indexOf(extraStr)
- + extraStr.length(), tempFileData.length());
- byte[] temp = new sun.misc.BASE64Decoder().decodeBuffer(finalData);
- dataContents = new String(temp);
- }
- catch( Exception e )
- {
- e.printStackTrace();
- }
- return dataContents;
- }
- /**
- * This method is used to search a particular image in a image directory.
- * In this method, it will search for the image contents for the image
- * you are passing.
- * @param imageToSearch of type String indicating the file name of the image
- * @param imageFolderToSearch of type String indicating the name of the directory
- * which contains the images
- * @return true if image is found else false
- * @author Debadatta Mishra(PIKU)
- */
- public static boolean searchImage( String imageToSearch , String imageFolderToSearch )
- {
- boolean searchFlag = false;
- try
- {
- String searchPhotoStr = getImageAsString(imageToSearch);
- File files = new File( imageFolderToSearch );
- File[] photosFiles = files.listFiles();
- for( int i = 0 ; i < photosFiles.length ; i++ )
- {
- String photoFilePath = photosFiles[i].getAbsolutePath();
- String photosStr = getImageAsString(photoFilePath);
- if( searchPhotoStr.equals(photosStr))
- {
- searchFlag = true;
- break;
- }
- else
- {
- continue;
- }
- }
- }
- catch( Exception e )
- {
- e.printStackTrace();
- }
- return searchFlag ;
- }
- /**
- * This method is used to search for a particular image found in a directory
- * and it will return the full path of the image found. Sometimes it is required
- * to find out the particular image and the path of the image so that the path
- * String can be used for further processing.
- * @param imageToSearch of type String indicating the file name of the image
- * @param imageFolderToSearch of type String indicating the name of the directory
- * which contains the images
- * @return the full path of the image
- * @author Debadatta Mishra(PIKU)
- */
- public static String searchAndGetImageName( final String imageToSearch , final String imageFolderToSearch )
- {
- String foundImageName = null;
- try
- {
- String searchPhotoStr = ImageAnalyzerUtil.getImageAsString(imageToSearch);
- File files = new File( imageFolderToSearch );
- File[] photosFiles = files.listFiles();
- for( int i = 0 , n = photosFiles.length; i < n ; i++ )
- {
- final String photoFilePath = photosFiles[i].getAbsolutePath();
- final String photosStr = ImageAnalyzerUtil.getImageAsString(photoFilePath);
- if( searchPhotoStr.equals(photosStr))
- {
- foundImageName = photosFiles[i].getAbsolutePath();
- break;
- }
- else
- {
- continue;
- }
- }
- }
- catch( Exception e )
- {
- e.printStackTrace();
- }
- return foundImageName;
- }
- /**
- * This method is used to convert an image into a text file.
- * @param imagePath of type String indicating the path of the image file
- * @author Debadatta Mishra(PIKU)
- */
- public static void convertImageToText( String imagePath )
- {
- File file = new File( imagePath );
- String fileName = file.getAbsolutePath();
- String textFilePath = new StringBuilder(fileName.substring(0, fileName
- .lastIndexOf("."))).append(".txt").toString();
- writeImageAsTextFile(textFilePath, getImageAsString(imagePath));
- /*
- * There may be requirement to delete the original image,
- * write the code here for this purpose.
- */
- }
- /**
- * This method is used to convert the text file into image.
- * However all text files will not be converted into images.
- * Those text files which have been converted from images files
- * will be converted back into image.
- * @param imageTextFilePath of type String indicating the converted text file
- * from image file.
- * @author Debadatta Mishra(PIKU)
- */
- public static void convertTextToImage( String imageTextFilePath )
- {
- try
- {
- File file = new File( imageTextFilePath );
- String fileName = file.getAbsolutePath();
- String imageFilePath = new StringBuilder(fileName.substring(0, fileName
- .lastIndexOf("."))).append(".").append(IMAGE_TYPE).toString();
- OutputStream out = new FileOutputStream( imageFilePath );
- byte[] imageBytes = readImageTextFile(imageTextFilePath);
- out.write(imageBytes);
- out.close();
- }
- catch( Exception e )
- {
- e.printStackTrace();
- }
- }
- }
The following test program provides the details of converting an into text file and vice versa.
Expand|Select|Wrap|Line Numbers
- package com.ddsoft.tornado.image.test;
- import com.ddsoft.tornado.core.image.ImageAnalyzerUtil;
- /**
- * This is a test harness class to test the
- * image conversion utility.
- * @author Debadatta Mishra(PIKU)
- *
- */
- public class ConvertImageTest
- {
- public static void main(String[] args)
- {
- String sourceImagePath = "data/IMG_2526.JPG";
- //Convert the image into text file
- ImageAnalyzerUtil.convertImageToText(sourceImagePath);
- //Convert the image text file back into actual image file
- ImageAnalyzerUtil.convertTextToImage("data/IMG_2526.txt");
- }
- }
Expand|Select|Wrap|Line Numbers
- package com.ddsoft.tornado.image.test;
- import com.ddsoft.tornado.core.image.ImageAnalyzerUtil;
- /**
- * This is a testharness class to hide the information inside an image
- * @author Debadatta Mishra(PIKU)
- *
- */
- public class HideDataTest
- {
- public static void main(String[] args)
- {
- String secretData = "It contains all my secret materials and my bank information details";
- String destinationImathPath = "data/secretImage.jpg";
- //Hide the information inside the image
- ImageAnalyzerUtil.hideTextDataInsideImage(destinationImathPath,
- secretData);
- //Get back the data hidden inside an image
- String hiddenData = ImageAnalyzerUtil
- .getHiddenDataFromImage(destinationImathPath);
- System.out.println(hiddenData);
- }
- }
Expand|Select|Wrap|Line Numbers
- package com.ddsoft.tornado.image.test;
- import com.ddsoft.tornado.core.image.ImageAnalyzerUtil;
- /**
- * This is a testharness class to search for an image
- * @author Debadatta Mishra(PIKU)
- *
- */
- public class ImageSearchTest
- {
- public static void main(String[] args)
- {
- try
- {
- String photoPath = "photos";
- String searchPhotoPath = "data/PhotoToSearch.JPG";
- //Search the image inside the directory of images
- boolean searchFlag = ImageAnalyzerUtil.searchImage(searchPhotoPath, photoPath);
- if( searchFlag )
- System.out.println("Image Found");
- else
- System.out.println("Specified Image Not Found");
- //Search and get the full path of the image inside a directory of images
- System.out.println("Found Image Name----->"+ImageAnalyzerUtil.searchAndGetImageName(searchPhotoPath, photoPath));
- }
- catch( Exception e )
- {
- e.printStackTrace();
- }
- }
- }
package com.ddsoft.tornado.image.test;
Expand|Select|Wrap|Line Numbers
- import com.ddsoft.tornado.core.image.ImageAnalyzerUtil;
- /**
- * This is a testharness class to check the converted image size
- * @author Debadatta Mishra(PIKU)
- *
- */
- public class MinimizeImageSizeTest
- {
- public static void main(String[] args) throws Exception
- {
- String originalImageSrcPath = "data/IMG_2542.JPG";
- ImageAnalyzerUtil.convertImageToText(originalImageSrcPath);
- ImageAnalyzerUtil.convertTextToImage("data/IMG_2542.txt");
- }
- }
OS Name : Windows Vista
Files of type : .jpg
Java : 1.6.0_16
Java Editor : Eclipse 3.2
Conclusion
I hope that you will enjoy my article. This article does not bear any commercial significance , it is only meant for learning. There may be many limitations in this program, I have given it as trick and twik in Java. You can download the full source code . In case of any problem or errors , feel free to contact me in the email debadatta.mishra@gmail.com .