Tuesday, November 29, 2016

Signing your modified android apk

While installing modified apk,I saw an error stating INSTALL_PARSE_FAILED_NO_CERTIFICATES.
After some research I found the solution for same.

Pre-install:
1) Install Android studio at https://developer.android.com/studio/index.html While Installation, it will ask path for android sdk, configure that path as per your need.
2) In my case it was like C:\Users\anurag\AppData\Local\Android\sdk1.
3) We are mainly interested in adb.exe which is present inside platform-tools, so for me the desired adb.exe path was C:\Users\anjain\AppData\Local\Android\sdk1\platform-tools\adb.exe
4) Add adb.exe in your system environment variables so that you can access adb from command prompt directly.


Problem:
1) Suppose you modified an apk named myapk.apk
2) You try to install the apk using
 adb install myapk.apk  
3) This returns an error Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]
4) This happens because your apk need to be signed again after you modified your apk.

How to sign your jar:

1) Copy the debug.keystore from C:\Users\<YOUR_USERNAME>\.android and place it in the same directory where your modified apk is present.
2) Change extension of your apk file to zip and open it using software like winzip and winrar. (For example your apk was myapk.apk then rename to myapk.zip)
3) Move to META-INF directory inside the myapk.zip.
4) Delete the 2 files with extension SF and RSA. For my case it was CERT.SF & CERT.RSA. For same reason I used CERT in step 7 & 8
5) Close winzip and rename the extension again to apk (For example your apk was myapk.zip then rename to myapk.apk)
6) Open command prompt and point to the directory where your modified apk is present
7) Enter below command: (Password: android)
 keytool -genkey -v -keystore debug.keystore -alias CERT -keyalg RSA -keysize 2048 -validity 20000  
8) Enter below command:
 jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore debug.keystore <Your apk filename with extension> CERT  
9) Verify if jar was signed properly by hitting below command:
 jarsigner -verify <Your apk filename with extension>  
10) If you dont see any error then everything is fine and you can now simply use below command to install in your smartphone
 adb install <Your apk filename with extension>  

Reference:
https://www.kingoapp.com/root-tutorials/how-to-enable-usb-debugging-mode-on-android.htm
https://developer.android.com/studio/index.html
https://dzone.com/articles/android-solution-install-parse-1

Hope it helps :)

Extract APK directly from Google Play Store without using any third party service

Earlier, I was using a third party service to get apk for my favorite apps. But I wanted to know how are they actually extracting those apk from Google play.
After some research, I found this way which can help you get apk from official Google Playstore in 5 minutes once you have proper setup.

Pre-install:
1) Install Android studio at https://developer.android.com/studio/index.html While Installation, it will ask path for android sdk, configure that path as per your need.
2) In my case it was like C:\Users\anurag\AppData\Local\Android\sdk1.
3) We are mainly interested in adb.exe which is present inside platform-tools folder of android sdk, so for me the desired adb.exe path was C:\Users\anurag\AppData\Local\Android\sdk1\platform-tools\adb.exe
4) Add adb.exe in your system environment variables so that you can access adb from command prompt directly.

Pre-requisite:
Get your package name:
1) Suppose you are installing "Clash of Clans" from Google Play, your url looks like https://play.google.com/store/apps/details?id=com.supercell.clashofclans&hl=en
2) Here the param value of id is com.supercell.clashofclans, which is also the package name.
3) Hence package name of this url is com.supercell.clashofclans

How to do:

1) Install the apk from google playstore on your smart phone or tablet
2) Make sure you have enabled the USB debugging on your android device. (How to do -> https://www.kingoapp.com/root-tutorials/how-to-enable-usb-debugging-mode-on-android.htm)
3) Now we use the adb.exe which comes along with the Android studio as explained in Pre-Install step
4) Connect your smart phone to your laptop using a usb cable
5) Now you need to extract the package name which is explained in Pre-requisite section. Assume package name is My_Package
6) Open command prompt
7) Type below and hit enter
 adb pull /data/app/MY_Package.apk  
8) APK is extracted on your PC to the directory pointed in cmd.

Complexity:
Once you have the installed sdk tools and enabled usb debugging, it becomes 5 min job to extract any apk.

Reference:
https://www.kingoapp.com/root-tutorials/how-to-enable-usb-debugging-mode-on-android.htm
https://developer.android.com/studio/index.html


Thursday, November 24, 2016

Unzip files using Java

We will unzip a zip file with Java using a third party library. But yes, you can also unzip the zip using pure Java without any third party library.

Language Used:
Java

Git Repo:
https://cooltrickshome.blogspot.in/2016/11/unzip-files-using-java.html

Reference:

Without using any third party: http://www.codejava.net/java-se/file-io/programmatically-extract-a-zip-file-using-java

Using Third party library : http://stackoverflow.com/questions/10633595/java-zip-how-to-unzip-folder

POM Dependency:
 <!-- https://mvnrepository.com/artifact/net.lingala.zip4j/zip4j -->  
 <dependency>  
   <groupId>net.lingala.zip4j</groupId>  
   <artifactId>zip4j</artifactId>  
   <version>1.3.1</version>  
 </dependency>  

Program:

Main method:
      public static void main(String[] args) {  
           // TODO Auto-generated method stub  
           Scanner s=new Scanner(System.in);  
           System.out.println("Please enter the zip file to be unzipped");  
           String zipFile=s.nextLine();  
           System.out.println("Please enter the password for zip file (type none if no password)");  
           String password=s.nextLine();  
           File f=new File(zipFile);  
           //Your password if any  
           unzipFile(zipFile, f.getParent(),password);  
           System.out.println("Extracted zip content at "+f.getParent());  
           s.close();  
      }  

How it works:
1) We make a scanner object to take user input
2) We ask user the file to be zipped
3) We ask password from user if needed
4) We call unzipFile method which unzip the file. It take 3 parameters.
5) First param defines the file to be unzipped
6) Second param defines the path where file will be extracted
7) Third param defines the password to be used for extracting zip file

unzipFile method:
      public static void unzipFile(String sourceZip, String destination, String password)  
      {  
           try {  
             ZipFile zipFile = new ZipFile(sourceZip);  
             if (zipFile.isEncrypted()) {  
               zipFile.setPassword(password);  
             }  
             zipFile.extractAll(destination);  
           } catch (ZipException e) {  
             e.printStackTrace();  
           }  
      }  

How it works:
1) We make an object of ZipFile pointing to the zip file to be unzipped
2) isEncrypted tell if the zip file require password for extraction
3) If password is needed we use setPassword to set the password for extraction
4) extractAll retreives the content of the zip file

Output:
 Please enter the zip file to be unzipped  
 C:\Users\anurag\Desktop\images.zip  
 Please enter the password for zip file (type none if no password)  
 Your password if any  
 Extracted zip content at C:\Users\anurag\Desktop  

Full Program:
 package com.cooltrickshome;  
 import java.io.File;  
 import java.util.Scanner;  
 import net.lingala.zip4j.core.ZipFile;  
 import net.lingala.zip4j.exception.ZipException;  
 public class UnzipFile {  
      /**  
       * @param args  
       */  
      public static void main(String[] args) {  
           // TODO Auto-generated method stub  
           Scanner s=new Scanner(System.in);  
           System.out.println("Please enter the zip file to be unzipped");  
           String zipFile=s.nextLine();  
           System.out.println("Please enter the password for zip file (type none if no password)");  
           String password=s.nextLine();  
           File f=new File(zipFile);  
           //Your password if any  
           unzipFile(zipFile, f.getParent(),password);  
           System.out.println("Extracted zip content at "+f.getParent());  
           s.close();  
      }  
      public static void unzipFile(String sourceZip, String destination, String password)  
      {  
           try {  
             ZipFile zipFile = new ZipFile(sourceZip);  
             if (zipFile.isEncrypted()) {  
               zipFile.setPassword(password);  
             }  
             zipFile.extractAll(destination);  
           } catch (ZipException e) {  
             e.printStackTrace();  
           }  
      }  
 }  

Hope it helps :)

Wednesday, November 23, 2016

Zip Folder using Java

You can zip your folders/files using Java

Language Used:
Java

Git Repo:
https://github.com/csanuragjain/extra/tree/master/Compression/Zip%20Folder

Reference:

Without any third party library : http://www.java2s.com/Code/Java/File-Input-Output/UseJavacodetozipafolder.htm

Using third party library: http://howtodoinjava.com/core-java/io/how-to-create-password-protected-zip-files-in-java/

Program:

Main method:
      public static void main(String[] a) throws Exception {  
           Scanner s = new Scanner(System.in);  
           System.out.println("Enter the file/folder to be zipped");  
           String zipFile = s.nextLine();  
           File f = new File(zipFile);  
           String zipFileName = f.getName() + ".zip";  
           if (f.isDirectory()) {  
                zipFolder(zipFile, zipFileName);  
           } else {  
                zipFile(zipFile, zipFileName);  
           }  
           System.out.println(zipFileName + " has been generated at "  
                     + new File("").getAbsolutePath());  
           s.close();  
      }  

How it works:
1) First we ask user the folder or file to be zipped.
2) We check if the given is file or folder
3) If it is file we call zipFile method passing the file to be zipped
4) If it is directory we call zipFolder method passing the folder to be zipped

zipFile Method:
      static public void zipFile(String srcFile, String destZipFile)  
                throws Exception {  
           ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(destZipFile));  
           File folder = new File(srcFile);  
           byte[] buf = new byte[1024];  
           int len;  
           FileInputStream in = new FileInputStream(srcFile);  
           zip.putNextEntry(new ZipEntry(folder.getName()));  
           while ((len = in.read(buf)) > 0) {  
                zip.write(buf, 0, len);  
           }  
           zip.close();  
      }  

How it works:
1) We make a zipoutputstream object pointing to the destination zip file to be created
2) We make a File object pointing to the source file to be zipped
3) We start reading the source file using read method and write it in the zip object made in step1
4) Finally our file is zipped

zipFolder method:
      static public void zipFolder(String srcFolder, String destZipFile)  
                throws Exception {  
           ZipOutputStream zip = null;  
           FileOutputStream fileWriter = null;  
           fileWriter = new FileOutputStream(destZipFile);  
           zip = new ZipOutputStream(fileWriter);  
           addFolderToZip("", srcFolder, zip);  
           zip.flush();  
           zip.close();  
      }  

How it works:
1) We make an object of zipoutputstream pointing to the destination zip file to be written
2) We call addFolderToZip method passing 3 argument
3) First argument defines the parent. So for example if we want to zip a.txt which was present within folder abc then first argument will be abc. For the first time parent would be ""
4) Second argument defines the source folder to be zipped
5) Third argument is the object pointing to output zip file to be written.

addFolderToZip method:
      static private void addFolderToZip(String path, String srcFolder,  
                ZipOutputStream zip) throws Exception {  
           File folder = new File(srcFolder);  
           for (String fileName : folder.list()) {  
                if (path.equals("")) {  
                     addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip);  
                } else {  
                     addFileToZip(path + "/" + folder.getName(), srcFolder + "/"  
                               + fileName, zip);  
                }  
           }  
      }  

How it works:
1) We iterate through each of files/folder present in the source folder to be zipped
2) For each of the file/folder scanned if it does not have parent then path is "" otherwise path has some value
3) To understand path, we take an example assume user gave c:\abc folder to be zipped. C:\abc has a folder named b and b folder has a file named c.txt. So when c.txt comes to this method then path will be b which is the parent. Similarly when b folder comes to zip the parent is null so path will be ""

addFileToZip method:
      static private void addFileToZip(String path, String srcFile,  
                ZipOutputStream zip) throws Exception {  
           File folder = new File(srcFile);  
           if (folder.isDirectory()) {  
                addFolderToZip(path, srcFile, zip);  
           } else {  
                byte[] buf = new byte[1024];  
                int len;  
                FileInputStream in = new FileInputStream(srcFile);  
                zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));  
                while ((len = in.read(buf)) > 0) {  
                     zip.write(buf, 0, len);  
                }  
           }  
      }  

How it works:
1) We make a file object pointing to the source file/folder to be zipped.
2) If its is directory we call addFolderToZip method to get entries within it
3)Otherwise if it is file then we write it in the zip

Output:
 Enter the file/folder to be zipped  
 C:\Users\anurag\Desktop\images  
 images.zip has been generated at C:\Users\anurag\Desktop\zipfolder

Full Program:
 package com.cooltrickshome;  
 import java.io.File;  
 import java.io.FileInputStream;  
 import java.io.FileOutputStream;  
 import java.util.Scanner;  
 import java.util.zip.ZipEntry;  
 import java.util.zip.ZipOutputStream;  
 public class ZipFolder {  
      public static void main(String[] a) throws Exception {  
           Scanner s = new Scanner(System.in);  
           System.out.println("Enter the file/folder to be zipped");  
           String zipFile = s.nextLine();  
           File f = new File(zipFile);  
           String zipFileName = f.getName() + ".zip";  
           if (f.isDirectory()) {  
                zipFolder(zipFile, zipFileName);  
           } else {  
                zipFile(zipFile, zipFileName);  
           }  
           System.out.println(zipFileName + " has been generated at "  
                     + new File("").getAbsolutePath());  
           s.close();  
      }  
      static public void zipFile(String srcFile, String destZipFile)  
                throws Exception {  
           ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(destZipFile));  
           File folder = new File(srcFile);  
           byte[] buf = new byte[1024];  
           int len;  
           FileInputStream in = new FileInputStream(srcFile);  
           zip.putNextEntry(new ZipEntry(folder.getName()));  
           while ((len = in.read(buf)) > 0) {  
                zip.write(buf, 0, len);  
           }  
           zip.close();  
      }  
      static public void zipFolder(String srcFolder, String destZipFile)  
                throws Exception {  
           ZipOutputStream zip = null;  
           FileOutputStream fileWriter = null;  
           fileWriter = new FileOutputStream(destZipFile);  
           zip = new ZipOutputStream(fileWriter);  
           addFolderToZip("", srcFolder, zip);  
           zip.flush();  
           zip.close();  
      }  
      static private void addFileToZip(String path, String srcFile,  
                ZipOutputStream zip) throws Exception {  
           File folder = new File(srcFile);  
           if (folder.isDirectory()) {  
                addFolderToZip(path, srcFile, zip);  
           } else {  
                byte[] buf = new byte[1024];  
                int len;  
                FileInputStream in = new FileInputStream(srcFile);  
                zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));  
                while ((len = in.read(buf)) > 0) {  
                     zip.write(buf, 0, len);  
                }  
           }  
      }  
      static private void addFolderToZip(String path, String srcFolder,  
                ZipOutputStream zip) throws Exception {  
           File folder = new File(srcFolder);  
           for (String fileName : folder.list()) {  
                if (path.equals("")) {  
                     addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip);  
                } else {  
                     addFileToZip(path + "/" + folder.getName(), srcFolder + "/"  
                               + fileName, zip);  
                }  
           }  
      }  
 }  

Hope it helps :)

Convert Base64 encoded string to Image using Java

This program will help you convert a base64 string to an image and then save the image to the current directory using Java.

Language Used:
Java

Git Repo:
https://github.com/csanuragjain/extra/tree/master/Base64ToImage

Pom Dependency:
 <dependency>  
   <groupId>commons-codec</groupId>  
   <artifactId>commons-codec</artifactId>  
   <version>1.10</version>  
 </dependency>  

Program:

Main Method:
      public static void main(String[] args) throws IOException {  
           // TODO Auto-generated method stub  
           Scanner s=new Scanner(System.in);  
           System.out.println("Enter base64 string to be converted to image");  
           String base64=s.nextLine();  
           byte[] base64Val=convertToImg(base64);  
           writeByteToImageFile(base64Val, "image.png");  
           System.out.println("Saved the base64 as image in current directory with name image.png");  
      }  

How it works:
1) First we make a scanner object and ask user to enter the base64 string which need to be converted to image.
2) We call the convertToImg method which convert the base64 string to byte[]
3) We pass the above retrieved byte[] as argument to writeByteToImageFile method. This will convert the byte[] to image and will save as image.png which was the second argument.

convertToImg method:
 public static byte[] convertToImg(String base64) throws IOException  
      {  
           return Base64.decodeBase64(base64);  
      }  

How it works:
1) We pass the base64 string to Base64.decodeBase64 method which converts the base64 string to byte[]

writeByteToImageFile method:
 public static void writeByteToImageFile(byte[] imgBytes, String imgFileName) throws IOException  
      {  
           File imgFile = new File(imgFileName);  
           BufferedImage img = ImageIO.read(new ByteArrayInputStream(imgBytes));  
           ImageIO.write(img, "png", imgFile);  
      }  

How it works:
1) This method obtains the byte[] and the image file name
2) We make a file object pointing to image file name
3) We make a BufferedImage object from the image bytes we passed
4) We use the ImageIO.write to write the BufferedImage into a physical file.

Output:
 Enter base64 string to be converted to image  
 /9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxQPEBQQEBQVFRQUFRUUFA8UFRQUFBUUFBQWFhUUFRQYHCggGBolHRQVITEiJikrLjAuFx8zODMtNygtLisBCgoKDg0OGhAQGiwkHyQsLC0tLCwsLCwsLCwsLCwsLCwtLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLP/AABEIALIBGwMBEQACEQEDEQH/xAAbAAEAAQUBAAAAAAAAAAAAAAAAAQIDBAUGB//EAEQQAAEEAAQCBwUFBQcCBwAAAAEAAgMRBBIhMQVBBhMiUWFxgQcyUpGhQmJyscEUI4KS0SQzQ6LC8PFTsxUWc4Oyw+H/xAAbAQEAAgMBAQAAAAAAAAAAAAAAAQUCAwQGB//EADsRAAICAQIEAQkIAgEDBQAAAAABAhEDBCEFEjFBURMiYXGBkaGxwQYUMkJS0eHwFSPxM2JyJIKissL/2gAMAwEAAhEDEQA/ANvSuzxlCkFCkFCkFCkIoUhNCkIoUhNCkFCkIoUlk0KQUKQijn8diy4GEAnLI7OG75A6wPDc/wAi0zl2LPTYHflPRt6y1PjJZhQ7DDplGlithz8NavuCxc2zpxaOEHb3fiXuHSSQOMkYByiiXNe4NzaAk5tNlqnFSVMsMOWWKXNExouEYvGzvdA9wdExr2sa4Nz5dHW2rlsu1BcNzzK582aOGSbdX/dyOTysXF7+Nm94bjOuZqMrxo+M/ZcN60Fjxob6gHRWWPIpq0ec1GmlhlT6eJl0szRQpLFFlry/3Pd+M8/wjn57eai7MnFLqXGx13k95/3p6KTEqyoRQpCaFIRQpLFCkJoUhFCkFCkJoUlsUKQUKQihSWKFJYoUhNF2lBIpAKQCkAQCkApAKQCkApAWZMU1pq7I3a0FxHnW3qsXJI248GSf4UWzi/u15uZ+jisfKI6FoMj6tGHPxoM+xfk7/wDE8oZfcJfqRw3SSV0jHakNfMHyNBIGQnW63qjvpz3pcubdWW2nioJR8Ed/0V6M/tbZcsjIWxlrGMbED9gHMQHDTkPwlcWr133aahXU34sXlFdmbhuDYnBYloIYWvBaH2eqlHOI6dh5A0DtL2J1W3FrMedbdfAiWKUGbqDhAw0oxMAIonNHrbon1nZWurSA4AbluXxWvWYnnxOPfqvWv36GWN8krMfpZgGtLcZERkkLc5FEB7v7uUeDtGnvtveSuHhGtfN5GfXt9UTrNPGcb7GsifmHiNx3H+i9PGSas8rlxPHLlZaA63f3OTfi8XD4e4c91HUj8Hr+X8lZnB0bbj93YebjpfhdqbMeV99iQHHfKPDVx+en6puNisN8Sfl+ikgqpAKQCkApAKQCkAQCkApAKQCkAQEUgLmVRZIypYJypYGVARlSwTkSwMiWCMqAnKosGJiMM+Q1mys+FppzvN9HKPAD15LGXM1s6OjBPFjlc483tr6My8FwzDubQj20LXFxo/Oq8lXZHki6bPZaRaXPjU8a29PVegpxXR2J47Fxu7wSR6tJ28qURzSRsyaHFJbKvUcrxHDOgf1co31a4e64d4/UcvlfVCaktioz4ZYpVI10uFDgQRYcC0jvBFELJq9jUtuh0fQzixwcjTKew9ojld+G8kvpZsdz3b0FWcT0b1GHzfxR6enxR06fKoS9DPVHsa9pa4BzXDbkRy/5XlceWWN3ZYtJo5nCcfidLNhw/M+FwGur3NJytNDUnN2fHQ86XqdHqXmhclv8GVMcsZzkop0nXofjXtNV0jY2aOSJ7sRHFhyJpep6hjoi4ZgHSTvaxlg3kNu7Y0AIWM9Lj8t5Zdfr4m2WPynKpdE7/vqNVxuD9m6gtPXQTxCaJ7m5XuYQ05Hg7e80nkbquSsoT5kacmJJ7mNhnGV2QADNbi0OkLQNLJGYZuQ101Gi3RTe1nJqPJwjztbm8jioAb0KugPoNFvKZ7uyrKlkDKlgZUsDKgJyqAMqmwRlSwTlUWBkU2BlSwRlSwTlSwRlSwMqWCcqWC5SgyoUgoUgoUgoZUFDKgoUgoUgoUgoUgoiy05xuNCB9pvd58x4+ZWrNj54+k7+H6x6XLf5X1/f2Gxa4ObbToRYcO47EKsao9wmpK10OC6X4mQTdU+QPaynNprWkZuTq51+YK6cSVXRS6+c+fkbtdTV4TE2aK3JnCbELIyRvuDdJJMHGIy+NzPsMfm7H3WvsaeFGuWmiqtVwrDnnz/hfeu50Y9RKCrqZPs94GxmNxPFXEHr7ZEw3cZDi2UkkAH3QARqQToLpZYcLww5G+hGBVGvS373f1Ntx3oLw3FzPlkifJNO/N1Ynma0voAyFrXUABuf60tlG8t+0aBjIoWuDc5OWNrSQIoowM4b3knqgb5CvE7sPU05ehoOj0HZdJ8Ryt8m7/Wx/Cu2C7lJrZ3JRXY21LM4aGVBQyoKGVBQpBQpBQyoKFIKFIKGVBQpBQyoKGVBQpBQpBQyoKLmVRZlROVQBlU2CMqChlQDKgJyqAMqAZVIIyqATlUgtxS9Se1/duN38Djvf3TvfI3yOnHqMV+dE9FwjiCilgyP1P6fsXeI4SF8b+ua3IAXOcQLAAsuB3B52uRN3segyQg4vmWx5Nh5qIygu8dAPU7fK122ebo20LnPGp/hbp83bn0pZbkpo63gXReLFND8PPmG0j+qDSx3wuJeS53lY8VqeRp9Dcsafc9F4Z0dw8MTYxG12Ue+4NzknUmwNCSTsueUm3ZvSSVGYzhzGA9UBGXe9I0DOQNu0b+tqLJPLenmJ67GiCLaJrYGCye37zje+l0T9wrqwxqPrOPUTS3fRGxw2HEbGsGzQB4muZ8V19CglLmk2y7lQxoZUAyqQRlUAnKgIyqQTlUAZUAyqQMqgUMqAZVIGVQBlQDKgIyoC5SEikApAKQCkApAKQCkApAKQCkBZfNqWsGZ2x5NH4ncvIWfBRZko+JzPS+J0cIaX0xxA6ppIYQBZGTYNAHedSNAtUscbss9Nq8sovHzNr+9/ochiJOrNOFcqOhvuDd78Fi9jclYgnJ973fgB0/iPPy281HrMrrodJwPj7sNIJIzrs5h917fhP6Hl9DMkpKjKM3F2etdH+kcWLaOqcM32oSQJG+n2h4jRc0otdTqjNS6FrpX0rjwUTiSDKR+7hu3F3IkDUN7z6DWgkYWJzUUcBwnDDDkz4yRjZpLIEj2tIzG3HU6vJ3rbbvvtVRW7opM055ny4036kb6GVrxbHNcO9pDh8ws07OJpxdMrpSQKQCkApAKQCkApAKQCkApAKQCkApAKQCkApAXcqgmhlQUKQUKQmhlQihlQmhSChlQihSE0MqEUUvjvTX00+qBIlsdCgKA5DQISa3HYRsszHVndEDTT7jHOo5395ADabvz00IxfU2wbjF9k/j6jJwnD2RWQ0Zne8+gCdb5bD/k2bKlKjGU5PbsRi+GwyAmWOMgfac1unjm3CNIiM5x6M5DiGE4aHUyZ4PdDmmb6nK781zTz4I7ORc6bQcSzK4Ym14tV86OceRmc1rs4adHZXNNHYljhbT/AEO+6mM4yVxdmWTDlwy5csXF+DK4Yjdgc7rvPiszWVRcWkdK+V/vvNuvcDcN12aAdAvN6vJleRuR9H4Tp9Ni0sY6emq3fdvvfp9HYzG8Ts5iBfxbOHk4ahaYajJHozrzaXDmVZIJr0pM7LoHJ+3TPhdLK3LHnbq1+zg02XtJI7Q58laaTXZJ2m+h5DjfA9JiUZ448tt3TZXxbiLsNiZMO50bsj2t91zSQ8NIN5yNnjkur7+1kWNrw+JXL7OY5aOWpjkeyk6pflvbsbfKrI8nQyoKFIKFITQpBQyoRQyoKGVBQyoKGVBQyoTQpCKGVBQyoKLlIZikApCBSEikApAKQUKQCkApAKQGC7iUbrEbi/xjBI8QH+7fqsW0bo4Mj7Go4vxiaJrRhImCrzdcf/i2N2pJJJJPztYSlL8vxOrFpYO3mb9Ffz2OYb03xPWASBga13bjY3LmHMBzsxGmx/4VZm1ubHPlkkep0P2d0OqweUxylfg2tn4Okv7udp0m6Lx8RwLcVg3PcQ3rGsdI9wkA95ha4kCQUarmK8ozOWWGzZhw/wAnodRU4LbZ7K16U+v7o864e8ClUKVM951LmPcCQ9o7TdvEc2nwP9DyW/Dqnimmuncr+I6CGswuD/Euj8H+z7mwwdOaHDY6r0cWpK0fOJQcZOMlTXUw+NYbs9Y3dtA+LSf0Jv1K4uIYFPHzd18i84DrHh1CxN+bPb29n9P+DQPmIKpVBNHt5ZOWVM772O4jLippCdBDk9XyNI/7ZXVpIU2zz/H8qcYR9LZrOnHEBLxWctNgywt/lbEwj5tKOPNqov0onBUOETb7qXx2NxFxVrNMuX8DnM+jSFfnh5Qi+qMocaIGZjnGv8N+Utd4ZqzA9xv0KWzVLTY2tlR0mHlEjGvbq1zQ5p8HCx+azK5xadMuUpMSKQCkJFIBSAUhApCRSAUgJpARSAuUoJoUgoUgoUgoUgoUoFClIoUgoUgoUgo0vTCcswjwNC8iP0ce3/lDlD6G7BG5o5fhmMdGzKNlgiyRZxWPLXAOOh5oDneLgdYHN56H8x/vxVfxDHzQ5vAv/s5qfJ6l4m9pr4rf5X8D032LcVsT4Rx0FTRi9r7EgHheQ+biuPRztOJY8fwKM45V32frX8fI4/p3gRhOITxtFMLhIwfdlAeQPAOLh6Ll1WOsj9JbcIzPLpY31j5vu6fCjnuvtc/KWZk4PEOjvLsTZYdif0PiuvT66eHbqvAp9fwbDq3zfhl4+PrXf5mTisf1jCzJV6E2CK51zXbl4njljaSdtFRpvs/qMeeE5Sjyxae13s76V9TFweIdh5WTx+/G7MByPe0+BFj1VOmpLlfRnqNThWbG49+3r7Ht3Dpop42TM1bI1rmmqJaRYv5rmxVjbi2014M8pJN9Ucxx3oFBM8zQkxSZi86lzHONm3A6jU3Y+RXRi1zwZeaXnL4k5pZMuneBOlt8Oxw+KwksE3VTAtcOXIg7OaeYPevVYsscsFOD2Z5icJQfLI2LBotwR2fRo3hY/DO30bI9o+gCyRWZ1/sZs6UmmhSChSChSChSChSChSChSChSChSChSCiulBlQpBQpLFCkFCkFCkIoUm5NCkFCkFCkFHN9PB/Zmf+qP8AtyLFm/TLz/Ycth9giO9Gu4/IGsBPePzC15ZqEXJm7DhlmyLHHqznZ8fmFZQNRzvYhVuXVc8XGup6DS8J+75Y5ee3Frt/J2XstxhZjiR/0JAfLNH+oC5dKqmyz47NPBFf930ZZ9p+M6zH33RRtPn2j+Tgp1O8l6jHgcnHBL/y+iOWjeuVovoTszoStEjYXliCEB6J7NsWX4V8R/wZS0fgkAkH1c8eTVy6yLtTXdfFfxR5rWQUNRKPjv7/AObOutcjk2c9GPx3gQxuFsD99EXGN3M8ywnuP50vR8KzuOJPwtezr9Sl10F5VrxPN6XpE9ivO36Px5cLF4sz/wA5L/8AUpRV5t5svY2ZzHxV7rnZXafFo0Xy1I+S1ZcnJKC8XXwb+hOPGpKXoV/FGXS3GqhSChSWxQpBQpNxQpBQpBQpBQpBQpBRUoskUlgIAgFJYFIBSWAgCAIDQ9NY7wbz8LmH5uDf9Shm3BtM5HDQO6vrMrsmbJ1lHLmq8uba61pQmrosUn1MrB9HhjmTh2mVgbE47CUnMD6BoB8HlYZManFxZEdXLTZY5I9n8O551NgpGS9Q5jhKHZTFRL73oAb6a6bhU3k5KXLW57X71hniWRSXK63s9I6C9GMRA580obGXtDW5u1IG3buwNBdN3Olahdmm0ko7z2KDjHG8WVqGHdLv0RPtC6PxR4Z2JAJl61hfM425wLSyqFNA93QAbLPVYYRxOSW5o4Jr809ZDFKXmu9u3SzzqJU0j6FjM+A6LRM6DIWsEoDu/Y+4HEYqM6h8MTq/A+Qf/Yu7TRU8TjJWrPJ/aJcuXHkXWn8H/J3mMw/VurkdQVS6vTeQnS6Pp+xzabP5WN911Nhwkdg/iP5BWnC1WG/Syv17/wBvsPM+leAy418cf+K4Za5GQ5T8nWVf6LMsmNpflbX995w54uG77qzrmMDQGjYAADwGgXYUvU0/SXDh4iB/6oaDV5S5ru14EZbtYySdWdugSeRp90bXCy9Yxr9szQ6u6xdLKzjlFxk4vsXaSzEIAgFIBSWAlgIBSAUgKsqAZUAyoBSAZUBOVARlQDKgGVAMqAweO4frMLMwbmN1fiAtv1AUMzxupIy+jvR7Nw52DlI1ksvbzAe14c2xvlFeYXJKfncyLyMPN5WWOH8J/Z3SwwtfIOtLmkDSi1lAyGm2BpvyK3RyrltlfnwTnkqK2NozgEr+097YjVDI0SP8Le4AV90D1WDz77I2w0Krz37jAwpdRElZ2Ocx+Ww0uY4tzNBJoGg4CzQcFvi7VnBmx+Tm4nKe1KYMwIbzkmY3+UOf/pXNrXWFlt9n4OWui/BN/A8qYqJn0qBl4crVI6DLaVpZJUoFna+yAf2+U8hhiD6ysr8irDR/hl7Dyv2l64v/AHf/AJPQ+k+PETWtAt5NjwA3JXBxjNGMIw79fUV3CdO8k5SvZbFGF4sDA3KCHHQ8zmJqmgakknRatNrW8McWGPnP+/3wMtRouXNKWR+aYWL6PTGVmKLG1Ex37oOuSzetVlJALtM3qr7heGWmg1N227KziH+9eZ2LjCCARqCLB7weaujzxruPx3ECNw8V5ua6MfV4UM6tE/8AcvaXeEutr2/DI6vJ9Sj0HWV/Cg1seXK/TuZuVScgyoCcqAikAyoBlQE5UBGVAMqAqQBAEAQBAEAQBAEAQFL2WCO8EfNAbToziM0LL3LWn5gX9VwyXY9FF2kzeArWZGKcaC1rm/aflF+t/kVlRFnNzf30xGxlNfwtaw/VpXZi/Aim1n/VZ5d7V+I58RFh2nSJhe/uzyVlB8Q1t/8AuKv4hk6Q9p6b7Lab8ed+pfN/Q4liq2e1gZELqWuSOhdDLa5aWiSu1APQ/YzATLipeQbDGD4kyOcPlk+asdKqg36Tx/2kyXmhDwV+9/wb/pXJmnBBsBgF+IJv8153i2SM8/mu6VfM6ODwccDvxv5Fzhcv7MYZJGuLe27QEluYU19DUisw0s9oeK6+EuOCd5drWzfrObiF5m/J706fuNxjeOF4yxAguHZJFaHQvIOoA8as6L1WHlyJOLteJQ6jJ5FPm6mBHGGgNGwAAHgBQXeUDMTjA/dE9z4nejZWOP0BUM36Z1mj6yzg+zORyfHp3AxOr5kSj+VS+p3cRhtGXsNmhVBAEAQBAEAQBAEBNKCRSAUgFIBSAUgFIBSAUgFIBSAwXdbBmMWVzCc2Q5g5mY28tIBztsl2XQ70ToBqnjvdHfp9XypQl7zccExXVsfNiJW5avNdNy8iNTyrmuZrsWSe1msix8r2ROH7mNtuzSNJkL3fBFuSAXAXzJ0IGuVWzBypW9jC43xaLAwyTuBDC791E4jrJHlo059pzg9x33LjzA3c/koXM4Fher1ChhW7/rZ4hjcW+eR80pt8ji5x5WeQHIAUAO4BUeTI5ycmfSNHpYabDHFDt/WUNWo7YlxpWLN0WX43rW0Zl4OWNA9M6CXBggLrrnGZw78wAZf8DWaeJXJqs878nF7L59zzGojDNnllavw9S6e/qdPggyZ3baHBuuvfy/VYaLTxy5PPVpHFrM88GPzHTZlcTIlaGnTXT9QPS1dZdL94qC6/Jd/gU2DVPTt5Huq3+nxMaOIN29SSSTW1kr0GPHHHFRj0RR5csssnKT3ZXSzNZicXH9nm7xE8jzDSR+Sh9DPE6nF+lGHMcro3/DIPlJcfy7YP8KykXerhzYn7zb0oKEUgMHiPE2QaGy7fKKuu8kkALnz6rHhXnM69Losuo/AtvF9DLheHNa4XTgCL3oi9fmt6dqzmkuVtMrpSYikApAKQCkBNIKFIKFIKFIKFIKFIKACChSCi0/ENBy2L5iwAPxEmh5b+Cxckjbjwyn0KmFh9/ERt+6ynH0e41/lWp5X2R2Q0UPzS9xrekL4o2Atx0sWvvOh6xrtPdzMjAH1KRySZtlpcSONbx6e9MQ8+NRkH+Zi3GnyUPAujjDyQXtjeQcwkyNZIHd4e0UD5tKOKZlGHL+FtfI32F6TYdkbpZnua5jdesILnD4YsoAN6aAAncjmsHy4429jXPFnzzUFu30SPLuk3HpMfN1j9GtsRxXYY39XHSz+gCpdRqHll6D3nCuFw0WPxm+r+i9BqFzlsVtUGyJcasWbkVAqDMzuF4Tr5Az7O7z3MHva8u71WEpci5vd6+xya3NyY6XV7fu/Z86O0k6Swg5Q/bS2se5voWtIpcH3bI9381ZULHLltRdepnX9HJmSRNdHIxwcbLw4EA17p7iBy33Vro9PKEKrdnntfN5M3L0S232+BspZWPLWxHM1hJdLyc+i0Bp5gAuvlZHMGrzTYeTdlNrMkeVY4hdZXUKQUUYiPMxze9pHzFKCTUYXDuxUWVhy3GLkc0mnOboA2x2huddNNNVRcV+0GHRqKglOT7J9EvHrv4I9QsfOnfQyziB2HBzWPe0HqnuADjzb5g2LGveDVK6hkjkgpxezSa9p5uUHFuLXQp4hxlkERkcHEg5epAJkzmqZlFkk5m1V3mFXYuMmVQV/Azw6aWWVLp4+g4vEB78RI58mfrCMkcduAcbtjBvIQA0WLGhqxqaDVPymSur718j1WkisWKuiXS/n7Td8H6SPLmxTxmN1tjLXNc3K4U2yCLbZs0eQFbq1hrVzrHJUykzcNag8kXa3Zum8bgLxGH2SQAQ1xbZNDtgZdTpd1ei6PvWJy5eZWcT0OoUHNwdL+9OpsKW85aFIKJpBRCCibQWEFhBYQWEFhBYQWEFkAILJIQWYmK4ZDKC2SJjgd7aPPfdRRmskl0ZznEugkTtcO90TuTSTIw/PtD5nySjbHUNdTkMdhpsG/JO2r9141Y4d7Xc/LQ+CjodMZqStHN8Ux5nff2G6MHf3v8z+XmVUavP5SXKuiPacG0Cw4/KzXnS+C/kw1xF2AhJU0qDKLLlqDbYtKDmkrZmYUnKQTo42W99bA99anzK15JV0NawKU/KZN32XZfz4v3HbdB+hLuJZpZHmOBrsuZoGeRwGoZegAsW4g66VvW7T6byi5pdCu4lxX7s/J41cu99F/J0cvAuHYKRxw2Ma2dujsPJPC5k1f4UjTVOOzTfZJBo6g2OHkwy81+yzzetep12LmyQuukuXp7Uunrs6CKQOaHNNtIBB7wRY+itTyLtOiomt0FkNeCLBBHI6Ug3KkIs4THdPJMPUcUcb2RtjZ1ji67aMsp0NUHU308dPGL7LxzPJlyTabcnSrpzOvl8V7fVY8r5I+pG36K8cGM6+N7Q0tkc7q9x1chzVqBmou1NcwvTaHD5DDHBzc3Kkr6Wq2/YpuIYnGfOu/zOWxuFihbNBizLECYWjFwjNJEWPJJA3a17XbjvGhulWefjyNS3a+vcv4KOfFGWLa+3q7ew2TsVh+GyxSYIftUhgyMxsswk6priQXNaKYXuPZN5T2OYsKYZVjT2W5i8cptKV7GrxGMBzOlzZnEuc+UGi865nPrLv3HTkuGSlOVt2d0eWKpbHTcJgb1LQzUSOAD+b9dZPEUCR4DTSlOnhKeohFeK/cx1eSOPTTk/B/HY6hesPDWEIsILCE2EICAIAgCAIAhAQkIAgCAIDmPaLjYo8DIyUAukGSJv2s/wAY7soN35DnS0ajIseNv3FjwrSz1GpjGK2u36u/v6HjQaqA+oJE0hlRBCGIBQJk2hlZU0qCV1tl+OWv6LBxs3OaStnqvSrip4XwvDYCJ2WWRh617TRa33pqPIue8i+4OXdmk8WNRj1PKaHEtbq55sn4Vu/ovV+xwsPDCW2SGkjRmW68DqtuPhUXG5ydkZvtLkWT/VBcq8bt/t8T1Do5IW4LDggucGNjDW6lzm9gNbf4dzy1NAFWcPMgk+yPGan/AG6mbgvxSbS8Ld/A6nBcBZQfiQ2V++VwzRx+DGnQkfGRZ12FNHNPI5Fhh08ca9PiYvFsBh4pYpmRRgukEUrQxuWSOTs9ptUS12Ug7gAjYlQrNzSMfGYcYefq231b2h8Y1IY6yHxg8m+6Wg95A0AA6MU7VMrtZgS86KPPIejjZI8W8huVoxkdaktlE3WxvA2qiL2255isI3G5+F7e2ze9Q7hjX/Z6qqmn7TP6I4SITMfmcJWxZXig0SSDMXm93Np7SAQD2QdaK59LnxZJ1G066P8AvqNnEcWaEHzU4t9V8Nu3f3mb03wUcsYaTle8FmarAbdhzxuQ1+VwAs6Ghup1/k4pSfXsY8HllU2o/h6v1+j1/I0MXD8NhTnhijMxZl61rmyZczWtc4OsgkgEDWxnJNUAarLnqNRZ6KUY5Hdev0lOEjMDDMY2yRtaS2Ak20Ddzeyb0Hu1oLrkFxLLCeaOFupSrftv0/5NyxyUHkW6X9/q9xk9FeKmfH24NaDG8NbHeUvturyNHOoO1I5aUvUY9Fj0nL59yla+u3f4lZxzFemUo+Nv1f8ALO+XUeRCAIAgCAIAgCAIAgCEBCQgCAIDTYnpHEJxhInNfObGQkhrSBZDnVvoeyLPlutM88Ivlvc7sPDs+SHleVqHj+x577QuD4hk37RM8yxvoNkqmxnnHlHui7I7+ZJsqq1bnJ8z6fI9pwHyGOPkYqpf/b/jw9pyRC4j0rjRSVJiQVJgyEICCyA5S1RhHJzPY6PoJwz9oxbXEdiGpHeJB7DfVwvyaVuwQuV+BXcV1Xk8PIustvZ3/Yr4/wAV/buIF92xhDWfgiO/iC4k/wAS6MUfKZ0+y/vzK7LP7pw1r82T5P8Aj4s2jHWrc8wmen+z3AOGGZPKPjEI7mOe4mTzddD7o+8QuXNO3yo3YcSi3PuzY8X4kQcrVqOg5+WV7nNc7XKczWg3bqIsk0NidFJBmYjEl+GxL5KzmLJC3fK8E9SAfjMjm/Jo5WZj1VGGSuV2V4qIPY5nJzXNv8QI/Vdko2miijLlkpLscBBgZ24uaFot8QbI0xvLSWPaAXNzEa7AnfWtVSz4fmx1LE7e/o93sPTriODJC8qqL28eniXsRFM63yCTs0M0uYbnRrS4W7cnSxvsuXLi1E05ZdlHx+SN+HNpYNQwU3Lsvm/A6LonhgYnucAczsuou2gflZK40dk3uYPSAX1wb8LmgDwZl0+Sr8s+XWY3+lx+dnbgj/6aXpv9voc/0QYDxCu7rHjzFj8nn5L6Lq9Opzx5b/D9Sq41Pl0lrvS+v0PSVrPFhAEAQBAEAQBAEAQBCAhIQBACgPIPaFgzh+ImRprrQ2ZhBohzaa6q1BDm3f3lTa+Djk513PffZrPDPpXp5dY3t4p/z9DsOi/TqDERfs3EQ1riMpkc0GGUffGzD59ny2WOLURltLqNbwjLhfPhtx9HVfv60WON+zJkv73AyhoOojeS+M92SUWQPMO81M9NF7xGm43lh5uVc3p6P+f7uchjOgmOjNdTnHxMewj5Eg/RaXp5os48Y0sura9a/azCHRPGZ2MMDml7srS6gLonU3sACT4BTHT5JOqMM3F9Jjg5uV12pnRs9mEp96eMeTXu+hpdi4c+8vgUUvtWu2L/AOX8G84P7OcNDTpi6d3c4ZI778gNn1cQujHoscN3uVWr+0GqzrlT5V6OvvNL0y6BiIdfgxTbAfCTowE1na47NHMHYa7Clp1OjX4oHfwnj84vyWo3XZ9/V6SviIbwjAdSw3PNYLxvZFPeO5rRoPEg8ytEqxQpdTsxqWv1XNLovgvD2nD8LeO0RvsPwju9b+i36JJRfic/HZzlli/y1t9fp7DtuBcLfO+CMgtE5pr+9gcRI5vi0NcfQd4Xc5pJlNCLbR7PjpxDGI2ADSmtGzWtAG3cNBXkuNeJ2HLTPskk+JJ+pJQktQYcykPtzGcq95476OjW+YJPhz3wxeJwZ9YouoGVHgmhwcbcR7pcbo1VhooA0SLq9St0YKPQ4cmonk2bMlZGk1+IwMLJxjHnK9sfVZy6m5LLqI5mz/ugolJRVt7G2Esko+Sir3ujWx45ssU+Kfb4xIYIoTo05SAXd4JNm960Xm+J8+s1WHSYnXWbl3S3Wy/fxR3YMj0WPJml+Wo14t0+vtr2MtRdI2RR5I4i0C9C8EDcnWrKyjwLVXU865fFR3+LoiX2lTXm43frVHM8RxJnJe5rS9+tOFhjdL05VY0G5PmVaSjh0OnpK29t9236Tj0q1PEtX502lHfbol6PSynom8xYtskgoBrhZzZns93ONa2GbbkQu2Ecr0q1M52rVpVUb7ut+66va90XnFtZz4lgW6TVv0+nsvcenrI86EAQBAEAQBAEAQBAEAQBAEAQHmXTeET4yRj7GURhrhu3sB1j1e5a8mOORcsiz0OaeCsmN0zmJOFys2AkHe0gH1a46ehKqsvDZp+Y7PZaX7S42ks8Wn4rde7r8yvB4rFYY3CZ4uZDS4NPmAaPqtUdNqYdEdOXiHCs/wD1Gm//ABd+9I6fDcR424WBIQQCM8UDT/maDfmt0ceq8PkVmXPwS9pv2c37M6zorDiiwzY8/viS1jKjGSPS/c0txAJ8Gt8V36bHKMbn1PMcVz4cmXl098i8e7N8ukqwgIe0OBBFgiiDsQdCCgR4L0wleMXLFK8uMTura4naNvuepaQfMkqkzxayO+3Q+hcMywlpIuGzf4n6f708EX+A9GMVMDMyItjY0uzv7AeALyx373ntput+lxZFLmrY4OLa7TSx+RTuVqq6L2ntfRCJrYMI54owwuNnQtc4Ma7/AFfJdEt2yrgtkXMZjTIS74vo37I/XzJWLMzCji611H3G1mHxO3DfIaE9+g7wtuOK6s49XmaXJHqbHMt/PHxKzyc32GYKPKQ8UT5KfgymQmqaQD3nWvTmU54+KCxS7pmNJhWtBkyGV7QS3MQXEge63N2W3tpQWNQ69WbObJXKtl6P7v7Tmsa7JgIWkgvkkfLINjnJOYEHVpt2oOoNhU2ivLxfNkp1CCim147/AB3MNe3DQ44PrKTlXo3+Wxb4H0e/aWdbM8hhcQxjKzHI4tJc5wIGoNADYA3rQv3JtnFi00FFSe7a9hTxbgbIpgyHNmfHbs7hlDQ40brTUuvfcaKm4pu4I9NwOMYQm1stjWY7CuEwjDmtfEwPaXZmaDUNBeLfoNDtoddCF0cOhn0zWXIv9T82S9D23it/aZ63PpViaUbt/lXd9W38zu+BOecNGZGlri33CCC1tnKCDqOzWh179VYeTWNuCdpXT8V2+BQTjyursz0MQgCAICC4Dda5ZYR6s2ww5J9EygzBc09fhj3s6ocNzy7UU9eFolxSPaJ0x4RL80iDP4LRLik+0TdHhOPvIjrytT4lmfSjcuGYF4kdcVg9fqH3M1w/TrsOtKwesz/qM1osH6SOtKj73n/UZfc8H6UOtKfe8/6mPueD9KHWlT98z/qI+5YP0o1nEeDRYh/WyNOeg3MCRYF1fzKyWvzruPuWFbJGKejUXIvHrf5rauJ5l1SMXosfpLX/AJayua+OQhzSHNJANEbea2x4rLvE1y0Cfc6Vk2mup7xoD6Xp81n/AJVfpOR8I8JE9f4Kf8ov0j/EP9XwKTiD3fVYviv/AG/En/EL9XwMLE8VLPsfVYviz/SSuEL9Ri/+PO+EUtb4tPtE2LhEO7LkfEmPOZzWh3xFov5rB8TyvwNi4ZiXiZjps4omwRR8isHxDM+5muH4F2LcU56oDm5rGu8wTn/VWsZWkzW1ToiaShp7xNNHeT+g1J8AVjOahFyZMY26RciZlaAOXPmSdST4k2fVUksk5O2zuWOK7Fa1tvxMqRCi2CUtk0hanmfiY8q8DDxPC4pXFz2AuNW8W1xoULIIJ0C2Q1GSH4ZNGvJp8OT8cU/WipmEyNDY3FoGzdwn3jLd8zC0+Kq5UWXxTAghwcRsSBY76J2WS1WZfmIelwvblKoJZc7TIwOo6OIFtvmDyW2OvzruanoMHZGz69bVxPKutGp8LwvoVCfwW1cVl3RplwmHZk9eFtjxWPeJqlwh9pE9aFs/yeI1f4rL4oxHSk81Uz1mWfVltj0mGHSJQSudtvqdKVdCQoFlQUmRUFIK2hSQVUpIFKAMqCiKSySNEsDRQSQQpBFKAEYIUEFJQksYmAPFH5qGDSYnCOZysd4WLRJjFyxJK4sS5uxIU2QZeF4o1oLZbb2s7HBrnA2bcOyDrd6cw7TY1caTUReOpOmjizY2pWjKw2Pa92Z1jk1p5DmT4n6AeJXNqtSpvlj0N2HE47vqbJjwdQVyWbioJVglCSCVNEBTQASgVUnKRYypyiwWpyiyKUcosmk5RYpOUWKTlFlhYhAIGVKQVNQkqUklxqyRiyoKSAsSUEYKHKCSgqCAoJCzRDCxYCEgqWCkqAUlAW3KB3Ndi4xroPkFiyTVSDVYkkIQS1AbTg57RHhssog3DVmupBUjJClEEKQVBEGVtUmJKAkIClSCUAUkhDE//9k=  
 Saved the base64 as image in current directory with name image.png  

Full Program:
 package com.cooltrickshome;  
 import java.awt.image.BufferedImage;  
 import java.io.ByteArrayInputStream;  
 import java.io.File;  
 import java.io.IOException;  
 import java.util.Scanner;  
 import javax.imageio.ImageIO;  
 import org.apache.commons.codec.binary.Base64;  
 public class Base64ToImage {  
      /**  
       * @param args  
       */  
      public static void main(String[] args) throws IOException {  
           // TODO Auto-generated method stub  
           Scanner s=new Scanner(System.in);  
           System.out.println("Enter base64 string to be converted to image");  
           String base64=s.nextLine();  
           byte[] base64Val=convertToImg(base64);  
           writeByteToImageFile(base64Val, "image.png");  
           System.out.println("Saved the base64 as image in current directory with name image.png");  
      }  
      public static byte[] convertToImg(String base64) throws IOException  
      {  
           return Base64.decodeBase64(base64);  
      }  
      public static void writeByteToImageFile(byte[] imgBytes, String imgFileName) throws IOException  
      {  
           File imgFile = new File(imgFileName);  
           BufferedImage img = ImageIO.read(new ByteArrayInputStream(imgBytes));  
           ImageIO.write(img, "png", imgFile);  
      }  
 }  

Hope it helps :)

Tuesday, November 22, 2016

Convert Image to Base64 using Java

You can convert your images into Base64 using Java and then later use them in your HTML

Language Used:
Java

Git Repo:
https://github.com/csanuragjain/extra/tree/master/ImageToBase64

Pom Dependency:
 <dependency>  
   <groupId>commons-codec</groupId>  
   <artifactId>commons-codec</artifactId>  
   <version>1.10</version>  
 </dependency>  
 <dependency>  
   <groupId>org.apache.commons</groupId>  
   <artifactId>commons-io</artifactId>  
   <version>1.3.2</version>  
 </dependency>  

Program:

Main Method:
      public static void main(String[] args) throws IOException {  
           // TODO Auto-generated method stub  
           Scanner s=new Scanner(System.in);  
           System.out.println("Enter image path to be converted to base64 (eg. c:\\abc.jpg)");  
           String imgPath=s.nextLine();  
           File imgFile=new File(imgPath);  
           String base64Val=convertTobase64(imgFile);  
           System.out.println("Converted value ");  
           System.out.println(base64Val);  
      }  

How it works:
1) We make a scanner object
2) We take the image path from user
3) We make a file object pointing to the image path given by user
4) We call convertTobase64 which returns the base64 encoded valie
5) We print the base64 value to the user.

convertTobase64 Method:
      public static String convertTobase64(File imgFile) throws IOException  
      {  
           return Base64.encodeBase64String(FileUtils.readFileToByteArray(imgFile));  
      }  

How it works:
1) FileUtils.readFileToByteArray converts the File object passed by main method into byte array
2) Base64.encodeBase64String converts the byte array to base64 value

Sample Output:
 Enter image path to be converted to base64 (eg. c:\abc.jpg)  
 C:\Users\anjain\Desktop\images\2.png  
 Converted value   
 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  

Full Program:
 package com.cooltrickshome;  
 import java.io.File;  
 import java.io.IOException;  
 import java.util.Scanner;  
 import org.apache.commons.codec.binary.Base64;  
 import org.apache.commons.io.FileUtils;  
 public class ImageToBase64 {  
      /**  
       * @param args  
       * @throws IOException   
       */  
      public static void main(String[] args) throws IOException {  
           // TODO Auto-generated method stub  
           Scanner s=new Scanner(System.in);  
           System.out.println("Enter image path to be converted to base64 (eg. c:\\abc.jpg)");  
           String imgPath=s.nextLine();  
           File imgFile=new File(imgPath);  
           String base64Val=convertTobase64(imgFile);  
           System.out.println("Converted value ");  
           System.out.println(base64Val);  
      }  
      public static String convertTobase64(File imgFile) throws IOException  
      {  
           return Base64.encodeBase64String(FileUtils.readFileToByteArray(imgFile));  
      }  
 }  

Hope it helps :)

Sunday, November 20, 2016

Test connectivity to SQL Server without installing any tools

Recently I was working on a project where I was required to check if the connection string to sql server was valid or not.
I just wanted to have a quick check without having to install all SQL tools.

Reference:
I came across the below page which made this check super easy:
https://blogs.technet.microsoft.com/michaelgriswold/2014/01/06/the-easy-way-to-test-sql-connectivity/

Steps to Check:

1) Create a simple txt file like check.txt
2) Rename the file from check.txt to check.udl
3) Double click the udl file
4) Move to Connection tab
5) Enter your server name, username & password
6) Click on Test Connection
7) Done. A window prompt will come telling if the connection string is valid or not.

Sample Udl File:
https://github.com/csanuragjain/extra/tree/master/TestSQLServerConnectivity

Hope it helps :)

Saturday, November 19, 2016

Play Movies & Videos on Desktop Wallpaper using Java

This blog post will help you play movie/video on your desktop wallpaper.

Langauge Used:
Java & C++

Git Location:
https://github.com/csanuragjain/extra/tree/master/DesktopMovieWallpaper

Working Software:

Part 1 https://github.com/csanuragjain/extra/blob/master/DesktopMovieWallpaper/Working%20Software/Working%20Software.z01?raw=true
Part 2
https://github.com/csanuragjain/extra/blob/master/DesktopMovieWallpaper/Working%20Software/Working%20Software.zip?raw=true

Download both part and use winzip or winrar to extract.

Concept:

1) We ask user the video which he would like to set as desktop wallpaper
2) Now we convert the video to images using tutorial http://cooltrickshome.blogspot.com/2016/11/convert-movie-to-images-using-java.html
3) Assume step 2 converted the video to 100 images.
4) We will start a loop and set desktop wallpaper all the 100 images found in step 3 one by one.
5) Overall effect is a movie playing in desktop wallpaper

Note:
1) This program converts the video to images. The overall converted images will be of size greater than the video. Make sure you have sufficient space if you are trying to convert a big video.

Pom Dependency:
Please add the below pom dependency from https://mvnrepository.com/artifact/org.bytedeco/javacv :
 <dependency>  
   <groupId>org.bytedeco</groupId>  
   <artifactId>javacv</artifactId>  
   <version>1.0</version>  
 </dependency>  

Java Program:
Main method:
      public static void main(String[] args) throws InterruptedException, Exception, IOException {  
           Scanner s=new Scanner(System.in);  
            System.out.println("Enter the path of mp4 (for eg c:\\test.mp4)");  
            String mp4Path=s.nextLine();  
            File imgPath=new File("convert");  
            imgPath.delete();  
            imgPath.mkdirs();  
            String imagePath=imgPath.getAbsolutePath();  
            convertMovietoJPG(mp4Path, imagePath,"jpg",3);  
            System.out.println("Conversion complete. Please find the images at "+imagePath);  
            changeDesktopWallpaper(imagePath,5000);  
      }  

How it works:
1) We make a scanner object to read user input
2) We ask user to enter path of mp4 file
3) We make a new folder named convert in current project directory. This will be the directory where images extracted from video would be kept
4) We call convertMovietoJPG method which converts the mp4 to images. I kept frametoJump as 3 but you may change it as per your requirement. More details on this http://cooltrickshome.blogspot.com/2016/11/convert-movie-to-images-using-java.html
5) Finally we call changeDesktopWallpaper which will set the images extracted from movie as wallpaper one by one giving a movie effect.
6) First argument defines the path containing the converted image and 5000 represents the millisecond after which video will start replay after it completes.

convertMovietoJPG method:
       public static void convertMovietoJPG(String mp4Path, String imagePath, String imgType, int frameJump) throws Exception, IOException  
       {  
                 Java2DFrameConverter converter = new Java2DFrameConverter();  
          FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(mp4Path);  
          frameGrabber.start();  
          Frame frame;  
          double frameRate=frameGrabber.getFrameRate();  
          int imgNum=0;  
          System.out.println("Video has "+frameGrabber.getLengthInFrames()+" frames and has frame rate of "+frameRate);  
          try {           
            for(int ii=1;ii<=frameGrabber.getLengthInFrames();ii++){  
            imgNum++;       
            frameGrabber.setFrameNumber(ii);  
            frame = frameGrabber.grab();  
            BufferedImage bi = converter.convert(frame);  
            String path = imagePath+File.separator+imgNum+".jpg";  
            ImageIO.write(bi,imgType, new File(path));  
            ii+=frameJump;  
            }  
            frameGrabber.stop();  
          } catch (Exception e) {  
            e.printStackTrace();  
          }  
        }  


How it works:
1) Already covered the explanation at http://cooltrickshome.blogspot.com/2016/11/convert-movie-to-images-using-java.html

changeDesktopWallpaper method:
      public static void changeDesktopWallpaper(String path, int sleepTime) throws InterruptedException  
      {  
           System.out.println("Starting to replay video after every "+(sleepTime/1000)+"s");  
           File f=new File(path);  
           File[] filePath=f.listFiles();  
           while(true)  
           {  
           for(int i=1;i<=filePath.length;i++)  
           {       
           changeWallpaper(path+"\\"+i+".jpg");  
           }  
           Thread.sleep(sleepTime);  
           }  
      }  


How it works:
1) We point file array on all the images extracted from video
2) For each image we call changeWallpaper which changes the wallpaper to that image.
3) Once all images are complete it waits for sleepTime and then restarts from step2

C++ Program:

wallpaperchanger.h
 /* DO NOT EDIT THIS FILE - it is machine generated */  
 #include <jni.h>  
 /* Header for class com_cooltrickshome_DesktopMovieWallpaper */  
 #ifndef _Included_com_cooltrickshome_DesktopMovieWallpaper  
 #define _Included_com_cooltrickshome_DesktopMovieWallpaper  
 #ifdef __cplusplus  
 extern "C" {  
 #endif  
 /*  
  * Class:   com_cooltrickshome_DesktopMovieWallpaper  
  * Method:  changeWallpaper  
  * Signature: (Ljava/lang/String;)I  
  */  
 JNIEXPORT jint JNICALL Java_com_cooltrickshome_DesktopMovieWallpaper_changeWallpaper  
  (JNIEnv *, jclass, jstring);  
 #ifdef __cplusplus  
 }  
 #endif  
 #endif  

wallpaperchanger.cpp
  #include <iostream>  
  #include <windows.h>  
  #include <fstream>  
  #include <cstdlib>  
  #include <jni.h>  
  #include "wallpaperchanger.h"  
  JNIEXPORT jint JNICALL Java_com_cooltrickshome_DesktopMovieWallpaper_changeWallpaper  
  (JNIEnv *env, jclass, jstring wallpaper){  
  const char *wallpaper_file = env->GetStringUTFChars(wallpaper, JNI_FALSE);  
  int return_value = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void *)wallpaper_file, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);  
  env->ReleaseStringUTFChars(wallpaper, wallpaper_file);  
  }  

How it works:
1) changeWallpaper method used by Java is defined in wallpaperchanger.dll which is created using wallpaperchanger.h & wallpaperchanger.cpp (Conversion from cpp & h to dll is explained at https://cooltrickshome.blogspot.in/2016/11/creating-your-personal-keylogger-from.html)
2) For cpp code, wallpaper variable contains the path of the wallpaper which is passed by Java
3) First we need to convert it to const char* which is done using env->GetStringUTFChars
4) SystemParametersInfo method is used to convert the wallpaper. We pass the desktop wallpaper path in it to change the wallpaper
5) Now we release the converted string.

Output:
 Enter the path of mp4 (for eg c:\test.mp4)  
 C:\Users\anjain\Desktop\images\rough\1.mp4  
 Video has 132 frames and has frame rate of 25.0  
 Conversion complete. Please find the images at C:\Users\anjain\workspace\BrowserMobProxy\cooltrickshome\convert  
 Starting to replay video after every 5s  

Full Program:

DesktopMovieWallpaper.java
 package com.cooltrickshome;  
 import java.awt.image.BufferedImage;  
 import java.io.File;  
 import java.io.IOException;  
 import java.util.Scanner;  
 import javax.imageio.ImageIO;  
 import org.bytedeco.javacv.FFmpegFrameGrabber;  
 import org.bytedeco.javacv.Frame;  
 import org.bytedeco.javacv.Java2DFrameConverter;  
 import org.bytedeco.javacv.FrameGrabber.Exception;  
 public class DesktopMovieWallpaper {  
      public static native int changeWallpaper(String path);  
      static  
   {  
     System.loadLibrary("wallpaperchanger");  
   }  
      public static void changeDesktopWallpaper(String path, int sleepTime) throws InterruptedException  
      {  
           System.out.println("Starting to replay video after every "+(sleepTime/1000)+"s");  
           File f=new File(path);  
           File[] filePath=f.listFiles();  
           while(true)  
           {  
           for(int i=1;i<=filePath.length;i++)  
           {       
           changeWallpaper(path+"\\"+i+".jpg");  
           }  
           Thread.sleep(sleepTime);  
           }  
      }  
       public static void convertMovietoJPG(String mp4Path, String imagePath, String imgType, int frameJump) throws Exception, IOException  
       {  
                 Java2DFrameConverter converter = new Java2DFrameConverter();  
          FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(mp4Path);  
          frameGrabber.start();  
          Frame frame;  
          double frameRate=frameGrabber.getFrameRate();  
          int imgNum=0;  
          System.out.println("Video has "+frameGrabber.getLengthInFrames()+" frames and has frame rate of "+frameRate);  
          try {           
            for(int ii=1;ii<=frameGrabber.getLengthInFrames();ii++){  
            imgNum++;       
            frameGrabber.setFrameNumber(ii);  
            frame = frameGrabber.grab();  
            BufferedImage bi = converter.convert(frame);  
            String path = imagePath+File.separator+imgNum+".jpg";  
            ImageIO.write(bi,imgType, new File(path));  
            ii+=frameJump;  
            }  
            frameGrabber.stop();  
          } catch (Exception e) {  
            e.printStackTrace();  
          }  
        }  
      public static void main(String[] args) throws InterruptedException, Exception, IOException {  
           Scanner s=new Scanner(System.in);  
            System.out.println("Enter the path of mp4 (for eg c:\\test.mp4)");  
            String mp4Path=s.nextLine();  
            File imgPath=new File("convert");  
            imgPath.delete();  
            imgPath.mkdirs();  
            String imagePath=imgPath.getAbsolutePath();  
            convertMovietoJPG(mp4Path, imagePath,"jpg",3);  
            System.out.println("Conversion complete. Please find the images at "+imagePath);  
            changeDesktopWallpaper(imagePath,5000);  
      }  
 }  

wallpaperchanger.h
 /* DO NOT EDIT THIS FILE - it is machine generated */  
 #include <jni.h>  
 /* Header for class com_cooltrickshome_DesktopMovieWallpaper */  
 #ifndef _Included_com_cooltrickshome_DesktopMovieWallpaper  
 #define _Included_com_cooltrickshome_DesktopMovieWallpaper  
 #ifdef __cplusplus  
 extern "C" {  
 #endif  
 /*  
  * Class:   com_cooltrickshome_DesktopMovieWallpaper  
  * Method:  changeWallpaper  
  * Signature: (Ljava/lang/String;)I  
  */  
 JNIEXPORT jint JNICALL Java_com_cooltrickshome_DesktopMovieWallpaper_changeWallpaper  
  (JNIEnv *, jclass, jstring);  
 #ifdef __cplusplus  
 }  
 #endif  
 #endif  

wallpaperchanger.cpp
  #include <iostream>  
  #include <windows.h>  
  #include <fstream>  
  #include <cstdlib>  
  #include <jni.h>  
  #include "wallpaperchanger.h"  
  JNIEXPORT jint JNICALL Java_com_cooltrickshome_DesktopMovieWallpaper_changeWallpaper  
  (JNIEnv *env, jclass, jstring wallpaper){  
  const char *wallpaper_file = env->GetStringUTFChars(wallpaper, JNI_FALSE);  
  int return_value = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void *)wallpaper_file, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);  
  env->ReleaseStringUTFChars(wallpaper, wallpaper_file);  
  }  

Hope it helps :)

Convert Movie to Images using Java

This blog post will help you to convert any Movie/Video to Images using Java.

Language Used:
Java

Git Location:
https://github.com/csanuragjain/converter/tree/master/MovieToImage

Pom Dependency:
Please add the below pom dependency from https://mvnrepository.com/artifact/org.bytedeco/javacv :
 <dependency>  
   <groupId>org.bytedeco</groupId>  
   <artifactId>javacv</artifactId>  
   <version>1.0</version>  
 </dependency>  

Program:
Main method:
       public static void main(String []args) throws Exception, IOException  
        {  
                 Scanner s=new Scanner(System.in);  
                 System.out.println("Enter the path of mp4 (for eg c:\\test.mp4)");  
                 String mp4Path=s.nextLine();  
                 System.out.println("Enter the folder path where the images will be saved (eg c:\\convertedImages)");  
                 String imagePath=s.nextLine();  
                 convertMovietoJPG(mp4Path, imagePath,"jpg",0);  
        }  

How it works:
1) We make a scanner object to read user input
2) We ask user to enter path of mp4 file
3) We ask user to enter folder path of output images
4) We call convertMovietoJPG method which converts the mp4 to images.
5) convertMovietoJPG takes 4 arguments.
6) First argument define the mp4 path.
7) Second argument define the output image folder path.
8) Third argument tells the extension for output images.
9) Fourth argument tells if we want to save all frames from video or not. For example if I give it as 2 then Frame2,Frame4... and likewise would be stored and Frame1,Frame3... likewise would be ignored. This is done to reduce the size of output image folder.

convertMovietoJPG method:
       public static void convertMovietoJPG(String mp4Path, String imagePath, String imgType, int frameJump) throws Exception, IOException  
       {  
                 Java2DFrameConverter converter = new Java2DFrameConverter();  
          FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(mp4Path);  
          frameGrabber.start();  
          Frame frame;  
          double frameRate=frameGrabber.getFrameRate();  
          int imgNum=0;  
          System.out.println("Video has "+frameGrabber.getLengthInFrames()+" frames and has frame rate of "+frameRate);  
          try {           
            for(int ii=1;ii<=frameGrabber.getLengthInFrames();ii++){  
            imgNum++;       
            frameGrabber.setFrameNumber(ii);  
            frame = frameGrabber.grab();  
            BufferedImage bi = converter.convert(frame);  
            String path = imagePath+File.separator+imgNum+".jpg";  
            ImageIO.write(bi,imgType, new File(path));  
            ii+=frameJump;  
            }  
            frameGrabber.stop();  
          } catch (Exception e) {  
            e.printStackTrace();  
          }  
        }  


How it works:
1) We create an object of Java2DFrameConverter which will help us to convert the frame obtained from video into BufferedImage.
2) We create an object of FFmpegFrameGrabber which will actually start grabbing the frames from the video
3) We start the frame grabber by calling the start method
4) Now we determine the video frame rate by using getFrameRate() method
5) Now we determine the number of frames peresent in the video using getLengthInFrames
6) We iterate through each frame in video.
7) For each loop iteration we tell frameGrabber the current frame by using setFrameNumber method
8) Using grab method we get the frame whose frame number is defined in step7
9) We convert the frame to BufferedImage using the convert method
10) We write the grabbed image to local disk using ImageIO.write
11) Assume we dont want all frames and only want to capture (All frames/2) then we keep frameJump to 2 so that ii always gets incremented by 2 and saving only half of actual images.
12) Now we stop the frameGrabber after the iteration completes which marks the completion of conversion.

Output:
Enter the path of mp4 (for eg c:\test.mp4)
C:\Users\anurag\Desktop\video\1.mp4
Enter the folder path where the images will be saved (eg c:\convertedImages)
C:\Users\anurag\Desktop\video\convert
Video has 132 frames and has frame rate of 25.0
Conversion complete. Please find the images at C:\Users\anurag\Desktop\video\convert

Reference:
http://stackoverflow.com/questions/15735716/how-can-i-get-a-frame-sample-jpeg-from-a-video-mov
https://code.google.com/archive/p/javacv/

Full Program:
 package com.cooltrickshome;  
 import java.awt.image.BufferedImage;  
 import java.io.File;  
 import java.io.IOException;  
 import java.util.Scanner;  
 import javax.imageio.ImageIO;  
 import org.bytedeco.javacv.FFmpegFrameGrabber;  
 import org.bytedeco.javacv.Frame;  
 import org.bytedeco.javacv.FrameGrabber.Exception;  
 import org.bytedeco.javacv.Java2DFrameConverter;  
 public class MovieToImage {  
      /**  
       * @param args  
       * @throws IOException  
       */  
       public static void main(String []args) throws Exception, IOException  
        {  
                 Scanner s=new Scanner(System.in);  
                 System.out.println("Enter the path of mp4 (for eg c:\\test.mp4)");  
                 String mp4Path=s.nextLine();  
                 System.out.println("Enter the folder path where the images will be saved (eg c:\\convertedImages)");  
                 String imagePath=s.nextLine();  
                 convertMovietoJPG(mp4Path, imagePath,"jpg",0);  
                 System.out.println("Conversion complete. Please find the images at "+imagePath);  
        }  
       public static void convertMovietoJPG(String mp4Path, String imagePath, String imgType, int frameJump) throws Exception, IOException  
       {  
                 Java2DFrameConverter converter = new Java2DFrameConverter();  
          FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(mp4Path);  
          frameGrabber.start();  
          Frame frame;  
          double frameRate=frameGrabber.getFrameRate();  
          int imgNum=0;  
          System.out.println("Video has "+frameGrabber.getLengthInFrames()+" frames and has frame rate of "+frameRate);  
          try {           
            for(int ii=1;ii<=frameGrabber.getLengthInFrames();ii++){  
            imgNum++;       
            frameGrabber.setFrameNumber(ii);  
            frame = frameGrabber.grab();  
            BufferedImage bi = converter.convert(frame);  
            String path = imagePath+File.separator+imgNum+".jpg";  
            ImageIO.write(bi,imgType, new File(path));  
            ii+=frameJump;  
            }  
            frameGrabber.stop();  
          } catch (Exception e) {  
            e.printStackTrace();  
          }  
        }  
 }  

Hope it helps :)

Thursday, November 17, 2016

Modify Clipboard content using Java

You can modify the text or images in clipboard using Java.

Software Features:

1) It can place any custom text on your clipboard
2) It can place any custom image to your clipboard

Language:
Java

Git Location:
https://github.com/csanuragjain/extra/tree/master/Clipboard/ModifyClipboard

Program:

Main method:
      public static void main(String[] args) throws Exception {  
           Toolkit toolkit = Toolkit.getDefaultToolkit();  
           Clipboard clipboard = toolkit.getSystemClipboard();  
           Scanner s=new Scanner(System.in);  
           System.out.println("Press 1 to copy text and 2 for copying image to clipboard");  
           int ch=s.nextInt();  
           if(ch==1)  
           {  
           setText(clipboard,"Text placed to clipboard by Java");  
           System.out.println("If you press Ctrl+v then you will see the text \"Text placed to clipboard by Java\"");  
           }  
           else if(ch==2)  
           {  
                Robot robot = new Robot();  
          Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();  
          Rectangle screen = new Rectangle( screenSize );  
          BufferedImage image = robot.createScreenCapture( screen );  
                setImageFromClipboard(clipboard, image);  
                System.out.println("Copied your desktop screenshot to your clipboard.");  
                System.out.println("Press Ctrl+v on paint and you will see your screenshot");  
           }  
      }  


How it works:
1) We access the clipboard object by using Toolkit.getDefaultToolkit().getSystemClipboard()
2) We ask user if he want to copy text or image on clipboard
3) If user choose to copy text, it calls setText method which will copy the text "Text placed to clipboard by Java" to your clipboard
4) If user choose to copy image then we take screenshot of the screen and call setImageFromClipboard method passing the image we took

setText method:
      public static void setText(Clipboard clipboard, String text)  
      {  
           StringSelection selection = new StringSelection(text);  
           clipboard.setContents(selection, selection);  
      }  


How it works:
1) Make object of StringSelection with the text to be copiedFile
2) we use setContent to set the text in the clipboard

setImageFromClipboard method:
      public static void setImageFromClipboard(Clipboard clipboard, BufferedImage image)  
                throws Exception  
                {  
     ImageSelection imgSel = new ImageSelection(image);  
     clipboard.setContents(imgSel, null );  
                }  


How it works:
1) We created a class ImageSelection since we dont have it predefined.
2) We make an object of ImageSelection and pass the image to be copied
3) we use setcontent and pass the ImageSelection object which copies the image to clipboard

ImageSelection class:
 class ImageSelection implements Transferable  
 {  
  private Image image;  
  public ImageSelection(Image image)  
  {  
   this.image = image;  
  }  
  // Returns supported flavors  
  public DataFlavor[] getTransferDataFlavors()  
  {  
   return new DataFlavor[] { DataFlavor.imageFlavor };  
  }  
  // Returns true if flavor is supported  
  public boolean isDataFlavorSupported(DataFlavor flavor)  
  {  
   return DataFlavor.imageFlavor.equals(flavor);  
  }  
  // Returns image  
  public Object getTransferData(DataFlavor flavor)  
    throws UnsupportedFlavorException, IOException  
  {  
   if (!DataFlavor.imageFlavor.equals(flavor))  
   {  
    throw new UnsupportedFlavorException(flavor);  
   }  
   return image;  
  }  

How it works:
1) This class implements Transferable so that we can use it to set image in clipboard
2) The contructor sets the image passed by user
3) getTransferData returns the image which will be placed in clipboard

Sample Output:
Press 1 to copy text and 2 for copying image to clipboard
2
Copied your desktop screenshot to your clipboard.
Press Ctrl+v on paint and you will see your screenshot

Hope it helps :)

Wednesday, November 16, 2016

Access Clipboard content using Java

You can access the text or images in clipboard using Java.

Software Features:

1) On copying any text, it gets placed in clipboard. This program can retrieve the text from clipboard
2) On using print screen, the image gets stored in clipboard. This program can retrieve the image from clipboard
3) When you copy file in windows, the file path get stored in clipboard. This program can retrieve the file path from clipboard and then copy the file to current directory.

Language:
Java

Git Location:
https://github.com/csanuragjain/extra/tree/master/Clipboard/AccessClipboard

Terms Used:
Current directory: Current directory in this post refer to the path from where you are running the program

Program:

Main method:
      public static void main(String[] args) throws Exception {  
           Toolkit toolkit = Toolkit.getDefaultToolkit();  
           Clipboard clipboard = toolkit.getSystemClipboard();  
           if (clipboard.isDataFlavorAvailable(DataFlavor.javaFileListFlavor))   
           {  
           getCopiedFile(clipboard);  
           }  
           if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor))   
           {  
           getText(clipboard);  
           }  
           if (clipboard.isDataFlavorAvailable(DataFlavor.imageFlavor))   
           {  
           getImageFromClipboard(clipboard);  
           }  
      }  


How it works:
1) We access the clipboard object by using Toolkit.getDefaultToolkit().getSystemClipboard()
2) Now we check what data is present in clipboard by calling isDataFlavorAvailable(DataFlavor)
3) If copied image is present in clipboard then clipboard.isDataFlavorAvailable(DataFlavor.javaFileListFlavor) will return true else false. If true, we call getCopiedFile(clipboard) which shows the name of all files which user copied and saves the copied file at current directory.
4) If text is present in clipboard then clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor) will return true else false. If true then we call getText(clipboard) which retrieves the text from clipboard and prints the same
5) If print screen image is present in clipboard then clipboard.isDataFlavorAvailable(DataFlavor.imageFlavor) return true else false. If true, we call getImageFromClipboard(clipboard) which retrieves the print screen image and saves it to your current directory

getCopiedFile method:
      public static Object getCopiedFile(Clipboard clipboard) throws UnsupportedFlavorException, IOException  
      {  
           Object result = clipboard.getData(DataFlavor.javaFileListFlavor);  
     List files = (List) result;  
     for (int i = 0; i < files.size(); i++) {  
       File file = (File) files.get(i);  
       File destFile=new File(file.getName());  
       copyFileUsingStream(file, destFile);  
       System.out.println("Copied file "+file.getName()+" to "+destFile.getAbsolutePath());  
     }  
           return result;  
      }  


How it works:
1) This method is called to retrieve the copied image and save those.
2) To explain we will take an example. Assume user copied c:\1.jpg & c:\2.jpg
3) Clipboard will now have 2 entries which is c:\1.jpg and c:\2.jpg
4) clipboard.getData(DataFlavor.javaFileListFlavor) will retrieve both the entries from clipboard in form of List<File>
5) We iterate through each entry of List<File>
6) For each File found we will copy it to the current directory. So in 1st iteration we will copy 1.jpg to the current directory & in next iteration it would copy 2.jpg to current directory.

getImageFromClipboard method:
      public static Image getImageFromClipboard(Clipboard clipboard)  
                throws Exception  
                {  
                 Transferable transferable = clipboard.getContents(null);  
                 Image img=(Image) transferable.getTransferData(DataFlavor.imageFlavor);  
                     if(img!=null)  
                     {  
                          counter++;  
                          BufferedImage buffered = (BufferedImage) img;  
                          ImageIO.write(buffered, "jpg", new File("copiedFile"+counter+".jpg"));  
                          System.out.println("Saved the clipboard image as copiedFile"+counter+".jpg");  
                     }  
                     return img;  
                }  


How it works:
1) Assume user press print screen on a page. Now the print screen image gets saved to clipboard.
2) clipboard.getContents(null).getTransferData(DataFlavor.imageFlavor) gets the image from the clipboard
3) We cast the Image to BufferedImage and then use ImageIO to write the image to a file which gets saved in current directory

getText method:
      public static String getText(Clipboard clipboard) throws UnsupportedFlavorException, IOException  
      {  
           String result = (String) clipboard.getData(DataFlavor.stringFlavor);  
           System.out.println("String from Clipboard:" + result);  
           return result;  
      }  


How it works:
1) Assume user copies a text and now the text is present in clipboard
2) clipboard.getData(DataFlavor.stringFlavor) gets the text from the clipboard and then we print it

copyFileUsingStream method:
      private static void copyFileUsingStream(File source, File dest) throws IOException {  
        InputStream is = null;  
        OutputStream os = null;  
        try {  
          is = new FileInputStream(source);  
          os = new FileOutputStream(dest);  
          byte[] buffer = new byte[1024];  
          int length;  
          while ((length = is.read(buffer)) > 0) {  
            os.write(buffer, 0, length);  
          }  
        } finally {  
          is.close();  
          os.close();  
        }  
      }  


How it works:
1) This method copies files from source to destination.

Sample Output:
Copied file 2.png to C:\Users\anurag\workspace\cooltrickshome\2.png
Copied file oranges-1117628_640.jpg to C:\Users\anurag\workspace\cooltrickshome\oranges-1117628_640.jpg

Full Program:
 package com.cooltrickshome;  
 import java.awt.Image;  
 import java.awt.Toolkit;  
 import java.awt.datatransfer.Clipboard;  
 import java.awt.datatransfer.DataFlavor;  
 import java.awt.datatransfer.Transferable;  
 import java.awt.datatransfer.UnsupportedFlavorException;  
 import java.awt.image.BufferedImage;  
 import java.io.File;  
 import java.io.FileInputStream;  
 import java.io.FileOutputStream;  
 import java.io.IOException;  
 import java.io.InputStream;  
 import java.io.OutputStream;  
 import java.util.ArrayList;  
 import java.util.List;  
 import javax.imageio.ImageIO;  
 public class AccessClipboard {  
      /**  
       * @param args  
       * @throws Exception   
       */  
      static int counter=0;  
      public static void main(String[] args) throws Exception {  
           Toolkit toolkit = Toolkit.getDefaultToolkit();  
           Clipboard clipboard = toolkit.getSystemClipboard();  
           if (clipboard.isDataFlavorAvailable(DataFlavor.javaFileListFlavor))   
           {  
           getCopiedFile(clipboard);  
           }  
           if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor))   
           {  
           getText(clipboard);  
           }  
           if (clipboard.isDataFlavorAvailable(DataFlavor.imageFlavor))   
           {  
           getImageFromClipboard(clipboard);  
           }  
      }  
      public static Object getCopiedFile(Clipboard clipboard) throws UnsupportedFlavorException, IOException  
      {  
           Object result = clipboard.getData(DataFlavor.javaFileListFlavor);  
     List files = (List) result;  
     for (int i = 0; i < files.size(); i++) {  
       File file = (File) files.get(i);  
       File destFile=new File(file.getName());  
       copyFileUsingStream(file, destFile);  
       System.out.println("Copied file "+file.getName()+" to "+destFile.getAbsolutePath());  
     }  
           return result;  
      }  
      public static Image getImageFromClipboard(Clipboard clipboard)  
                throws Exception  
                {  
                 Transferable transferable = clipboard.getContents(null);  
                 Image img=(Image) transferable.getTransferData(DataFlavor.imageFlavor);  
                     if(img!=null)  
                     {  
                          counter++;  
                          BufferedImage buffered = (BufferedImage) img;  
                          ImageIO.write(buffered, "jpg", new File("copiedFile"+counter+".jpg"));  
                          System.out.println("Saved the clipboard image as copiedFile"+counter+".jpg");  
                     }  
                     return img;  
                }  
      public static String getText(Clipboard clipboard) throws UnsupportedFlavorException, IOException  
      {  
           String result = (String) clipboard.getData(DataFlavor.stringFlavor);  
           System.out.println("String from Clipboard:" + result);  
           return result;  
      }  
      private static void copyFileUsingStream(File source, File dest) throws IOException {  
        InputStream is = null;  
        OutputStream os = null;  
        try {  
          is = new FileInputStream(source);  
          os = new FileOutputStream(dest);  
          byte[] buffer = new byte[1024];  
          int length;  
          while ((length = is.read(buffer)) > 0) {  
            os.write(buffer, 0, length);  
          }  
        } finally {  
          is.close();  
          os.close();  
        }  
      }  
 }  

Hope it helps :)