Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Sunday, April 13, 2008

Do I really understand Java? or Computer Science, for that matter?

Like I mentioned in my previous post, I was with Javaground being interviewed for the Developer position. It was an overall amazing and a great learning experience. I am so much thrilled for having interviewed with them that I have been thinking a lot on how I could be like them. The java we write is so lame. I gave a talk on optimizations and now I feel embarassed that I am not eligible to give such a talk. And I did cover a lot of material and left out a lot. But talking with the Javaground team made me realize that I am not as good I felt I was.

I was honored to be in their guest house along with a developer from their Canada team. He was Nigel and I should say that he was amazing and very impressive, very pleasant to talk and very down to earth. He told me simple things that no one would ever find in a book, I bet. So the aspect he told me was "comparisons with a 0(zero) is much faster than with any other numbers". This was just one of the quiet a lot of information he shared with me. Though not always "java" we talked about, he told me various other things - about life as a mobile developer, how mobile game works, stuff like that.

Anyway, I decided I would look into the "comparison with zero" to understand more. So just now I wrote two simple programs - Hello and Hello2. The Hello.java looks something like this:

public class Hello{
        public static void main(String[] args) {
                 int i = 0;
                 if(i < 1) System.out.println("Test");
        }
}

The result of running javap is shown. (After compiling with javac)
javap -c -private -verbose Hello

Let me show you the output ....

Compiled from Hello.java
public class Hello extends java.lang.Object {
    public Hello();
        /* Stack=1, Locals=1, Args_size=1 */
    public static void main(java.lang.String[]);
        /* Stack=2, Locals=2, Args_size=1 */
}

Method Hello()
   0 aload_0
   1 invokespecial #1 <Method java.lang.Object()>
   4 return

Method void main(java.lang.String[])
   0 iconst_0
   1 istore_1
   2 iload_1
   3 iconst_1
   4 if_icmpge 15
   7 getstatic #2 <Field java.io.PrintStream out>
  10 ldc #3 <String "test">
  12 invokevirtual #4 <Method void println(java.lang.String)>
  15 return

I have made the lines of interest bold. Now my Hello2.java looks like this:

public class Hello2{
        public static void main(String[] args) {
                 int i = 0;
                 if(i < 0) System.out.println("Test");
        }
}

Now let us look at the javap output shown in the listing.

Compiled from Hello2.java
public class Hello2 extends java.lang.Object {
    public Hello2();
        /* Stack=1, Locals=1, Args_size=1 */
    public static void main(java.lang.String[]);
        /* Stack=2, Locals=2, Args_size=1 */
}

Method Hello2()
   0 aload_0
   1 invokespecial #1 <Method java.lang.Object()>
   4 return

Method void main(java.lang.String[])
   0 iconst_0
   1 istore_1
   2 iload_1
   3 ifge 14
   6 getstatic #2 <Field java.io.PrintStream out>
   9 ldc #3 <String "test">
  11 invokevirtual #4 <Method void println(java.lang.String)>
  14 return

As you can see the highlighted section again, we would notice an operation missing. So let me put the areas of interest together, side by side.

i < 1

i < 0

   0 iconst_0
   1 istore_1
   2 iload_1
   3 iconst_1
   4 if_icmpge 15
   0 iconst_0
   1 istore_1
   2 iload_1
   3 ifge 14

Frankly, I do not understand the bytecode so well yet, but I do can make out that in comparison with a 1, there is an instruction that creates the constant 1. Where as for comparison with 0, that instruction is missing. I could recall something similar that we learning during Computer Architecture class and the Embedded Systems course that I attended. I wish I invested more time in those classes. How foolish I was back then?

This is not a big deal when you have server class machines or a laptop for that matter. Saving a couple of instructions - no big deal. But in a mobile environment, it makes sense. So out of 200000 odd lines that we write, if we could only save 2 instructions per 100 lines, that would save us 2000 instructions !!! and it is a lot given the limited resources of a mobile device.

I am very interested in gaining such knowledge and it is only possible, at the moment, when we work at companies like Javaground. I could get a job as a web developer or as a C# developer at any point of time in my life but opportunities like Javaground does not often come. And I have worked very hard for this opportunity. I gave 3 rigorous online tests, attended around 6 interviews and after all I wish if only I could prepare better. "If" i am lucky and "if" I get an offer from Javaground which is good enough for me to make a proper living, then I would see myself learning a lot from the immense talent that Javaground possess and hopefully one day see myself as one of their core people. I know there are a lot of such firms but at the moment, the only such firm that has interviewed me is Javaground. 

The two days made me realize, there is so much I should learn!

Wednesday, January 30, 2008

String comparisons : == vs. equals()

It is a well known that you cannot compare two objects obj1 and obj2 using == operator. == operator checks for the equality of the references not the equality of the objects. Just a little snippet is shown below

Point p1 = new Point(100,100);
Point p2
= new Point(100,100);
System.out.println(p1
==p2); // ??
The above code snippet, when run, displays "false" in the output console. But still both p1 and p2 refers to a coordinate (100,100). So if you wish to get your equality to be true for such cases (where the object content! matches), then you should be using "equals()" method. This works for almost all the classes shipped with JDK. For this to work on the objects of the classes that you write (eg: Employee class or Chair or Bench.java), then you should override the method "public boolean equals(Object two)" and implement your meaning of equality of the objects of your class. Also note that, it is highly recommended and important that you override the "int hashCode()" method when you override the "equals" method.

Anyway, now when we deal with String comparisons, one should remember that "Strings" are not value types but are reference types (I mean String is a class). So Strings have to compared for equality using equals method instead of == operator. But the way the JVM is implemented, there are cases under which the == returns true for matching strings. So what are the cases?

Case 1: Where == returns true

String s1 = "Krishna";
String s2 = "Krishna";
if(s1==s2)
System.out.println("Strings are equal!!");
else
System.out.println("You cannot use == here");

Trying running the code as it is and you see the "Strings are equal" on the console. Well can you guess why?

The reason for the == operator to work in this case is that the Java compiler optimizes the strings s1 and s2. Since they are both "initialized" to "Krishna", instead of having two different string objects, optimization is done by having only one object and both s1 and s2 refer to the same "Krishna" object. Remember that the == operator only works for "static" kind of initialization. So if it was the case where s1 = new String("Krishna"); then s1 == s2 would return false instead of true, though it appears both are being initialized to the same "Krishna". Let us see another case where s1 == s2 fails.

Case 2: Where == returns false and equals() return true

String s1 = "Krishna";
String s2 = new String(s1);
if(!(s1==s2))
System.out.println("You cannot use == here");
else if(s1.equals(s2))
System.out.println("You should use 'equals' method in all cases");
Anyway the moral of the story is that you should always use "equals" to compare strings and should never use == even though it works in few cases.

Thursday, January 03, 2008

Image Processing with Java


Small Background


This article is to help readers understand how to process images with Java. During my course work in Image Processing(8810) under Dr. Hamid R. Arabnia, I have developed this class that helps one to work on images, apply filters and other such operations. It lets you work with images at pixel level and is implemented well enough. Though my assignments were implemented in .NET for which I used Bitmap class, I wrote this utility class to help out my friends and surprisingly it did work very well. Well, cut the crap and lets go into some theory.


Practical Image


An image could be considered as a 2D array of Pixel. A pixel has a position (x,y) and intensity values (R,G,B). You have a color image and wish to covert the image into a gray scale image, then you extract these R,G,B values and then the gray level of that pixel in the simplest form is (R+G+B)/3 and replace each R,G,B with this average. Note that in image processing terminology, a gray scale image is different from a Black and white image. A Black and White image is also known as a Binary Image where the intensity of each pixel is either 0(Black) or 1(actually 255, white). A Gray Scale image has all R,G,B values equal.


Java Image Processing


There are several options in Java to develop image processing applications. The very well known library is the Java Advanced Imaging(JAI) Api. It is a very sophisticated API and does great work, but again, to understand JAI properly, one should really have a strong Image Processing fundamentals. Simpler options include the ImageIO API(again by Sun), ImageJ library and one very good library is the Hiof's Image Processing API. It can be found here. It is a very decent library and relatively old but does great job. And I have to market my own class. I do not call it a library but it has excellent methods that helps you work with raw pixel data. I call this library as ImageUtility and is available upon request. The following are the methods that are available in the ImageUtility:


1.LoadImage(String path) loads the image and returns the BufferedImage object

2.GetImageMatrix(BufferedImage img) returns the image passed as 2d array of integers. A pixel at (0,0) is accessed as returnedArray[0][0] and the value is between 0 to 255.

3.GetHistogram(int[][] matrix) - returns the int[] histogram of the passed matrix. A histogram is the distribution of intensities. For example, histogram[255] gives you the number of pixels whose intensity is White and histogram[0] gives the number of pixels whose intensity is Black.

4.GetImageFromMatrix(int[][] matrix) a function reverse to GetImageMatrix() method. Pass your matrix and get its bufferedImage object.

5.SaveImageToDisk(BufferedImage,String saveFileAs,String type) saves the image to the disk at the specified path(saveFileAs) as a image of type("jpg","png","gif")

6.GetBufferedImage(Image) Image is the super class of BufferedImage and yet is not straight forward to get a BufferedImage from an Image. This function does that exactly and trust me it is very useful.

7.GetHistogramImage(int[] histogram) returns the histogram as an Image, a graph that is more visual than an integer array.

8.ApplyFilter(int[][] filter,int[][] matrix) I should say this is the heart of the library. A Kernel/Filter is a 2D Array that does magic on an image. You can sharpen the image, do noise reduction(smoothing) and different other operations with this amazing filter. Consider the filter as a square piece of paper and your image as bigger sheet of paper. First put the smaller paper on the image paper such that both their (0,0) are on top of each other. Also both the horizontal and vertical borders of each should be aligned. I hope this gives and idea. Now you multiple each pixel positions and add the total value. For example, if you have a 3x3 kernel, first of all, you do a

   1: val = k[0][0]*i[0][0]+k[0][1]*i[0][1]+k[0][1]*i[0][1] +


   2: k[1][0]*i[1][0]+k[1][1]*i[1][1]+k[1][1]*i[1][1] +


   3: k[2][0]*i[2][0]+k[2][1]*i[2][1]+k[2][1]*i[2][1]




where k is the kernel array and i[][] is the image matrix.



Now you put the value at i[1][1] (the center of image where kernel is applied). Once the first position is applied, you just move the kernel by one pixel such that k[0][0] is now at i[0][1]. That way you move the kernel all the way till the row ends. Then you move by one pixel down and reapply the same way. That way you cover the entire image. This infact is a time consuming operation and thus it should be now obvious on why image processing suites such as Photoshop,Paint.NET and GiMP are CPU intesive.



Understanding kernels is very important. Most frequent Image processing operations could be done with Kernels. I recommend you take a look at some Image Processing book to get a list of some filters, I dont remember them now.



9. GetFilesList(dir) Just an out of field method. Given a directory path, it returns the list of files in that directory.



10.SaveImageListToDisk(ArrayList list,folderPath) Saves the images in the arraylist in the specified folder.



Well now it is time for me to explain some code. Some of you might not be interested in my code and might just want to know how to load images from disk, how to extract pixel information from the image, etc. The subsequent sections explains you this.



Reading an Image from Disk



We use ImageIO class to load the image. Shown below is the code that loads the image. It is exactly as in ImageUtility.LoadImage() method.





   1: public static BufferedImage LoadImage(String path) throws IOException


   2: {


   3: //Load the image


   4: BufferedImage img = ImageIO.read(new File(path));


   5: //If it is not a gray scale image


   6: if (img.getType() != BufferedImage.TYPE_BYTE_GRAY)


   7: {


   8: //Let us convert to Gray Scale.


   9: ColorConvertOp conv = new ColorConvertOp(ColorSpace


  10: .getInstance(ColorSpace.CS_GRAY), null);


  11: conv.filter(img, img);


  12: }


  13: return img;


  14: }




Saving the image to disk



Again we use ImageIO class. The following method is in my ImageUtility.java





   1: public static void SaveImageToDisk(BufferedImage img, String filename,


   2: String type) throws IOException


   3: {


   4: //very simple, use ImageIO.write()!!!!


   5: ImageIO.write(img, type, new File(filename));


   6: }


   7:  


   8:  


   9:  


  10:  




Extracting the image matrix, the raw pixel data



Get the WritableRaster using img.getRaster(). Then use getSample method from the raster to get the pixel intensity at the specified location(x,y). It is as simple as that.





   1: public static int[][] GetImageMatrix(BufferedImage img)


   2: {


   3:     int height = img.getHeight();


   4:     int width = img.getWidth();


   5:     int imageMatrix[][] = new int[height][width];


   6:     WritableRaster wr = img.getRaster();


   7:     for(int y = 0; y < height; y++)


   8:       for(int x = 0; x < width; x++)


   9:         imageMatrix[y][x] = (wr.getSample(x,y,0)


  10:                             +wr.getSample(x,y,1)


  11:                             +wr.getSample(x,y,2))/2;


  12:     return imageMatrix;


  13: }




Getting image from the matrix passed






Again, pretty straight forward operation like the GetImageMatrix() method. Get the WritableRaster and use wr.setPixel(x,y,pixel) where pixel is an integer array where pixel[0] is R, pixel[1] is G, pixel[2] is B. Look at the method.





   1: public static BufferedImage GetImageFromMatrix(int[][] matrix)


   2: {


   3:     int height = matrix.length;


   4:     int width = matrix[0].length;


   5:     BufferedImage img = new BufferedImage(width, height,


   6:                                           BufferedImage.TYPE_BYTE_GRAY);


   7:     WritableRaster wr = img.getRaster();


   8:     for(int y = 0; y < height; y++)


   9:         for(int x = 0; x< width; x++)


  10:         {


  11:             int[] pixel = new int[3];


  12:             for(int i =0; i<3; i++) pixel[0] = matrix[y][x];


  13:             wr.setPixel(x,y,pixel);


  14:         }


  15:     return img;


  16: }




How to apply filter?






The signature for the apply filter method is shown below. It returns the new matrix after the filter has been applied.





   1: public static int[][] ApplyFilter(double[][] filter, int[][] matrix)




Typical Image Processing Method



We have looked at the most fundamental operations that could be used to do amazing IP operations in a simple fashion. A Typical image processing operation could look something like this.





   1:  


   2: void Sharpen(String imagePath,String outputPath,int[][] sharpenFilter)


   3: {


   4:     BufferedImage actualImage = ImageUtility.LoadImage(imagePath);


   5:     int[][] actualImage_matrix = ImageUtility.GetImageMatrix(actualImage);


   6:     int[][] sharpenedImage_matrix = ImageUtility.ApplyFilter(sharpenFilter,actualImage_matrix);


   7:     BufferedImage sharpenedImage = ImageUtility.GetImageFromMatrix(sharpenedImage_matrix);


   8:     ImageUtility.SaveImageToDisk(sharpenedImage,outputPath,"jpg");


   9: }




The above image could actually be placed in the ImageUtility.java but sometimes you might want to repeatedly apply certain filters in a sequence. Anyway the above method gives the basic idea on how to do image processing operations. The sharpenFilter, like I said earlier, I dont remember, anyway it is just a 2D integer array. Actually a double[][] filter makes more sense. Anyway my idea behind this article is to give fundamental understanding on how to do image processing operations on images with ease. Not many internet resources has this simple a code to write an image processing java code. I hope this helps atleast a few people.





Email me at krishnabhargav@yahoo.com in case you need the complete ImageUtility or some guidance on Java Programming or Image Processing.

Wednesday, November 07, 2007

Java Game Programming using JGame

I came across this wonderful 2D Game Engine called JGame. This is a very good engine to write simple games and with just 100 odd lines of code, you can write wonderful games! I would post a series of tutorials shortly, but meanwhile it is a good point to start
http://www.13thmonkey.org/~boris/jgame/JGame/tutorial/
Great work Boris Van Schooten!! Really amazing!

Sunday, October 28, 2007

Project P2P Library

A good library for developing Peer-To-Peer applications is being developed by me and a friend. The aim is to enable ease of development of a Peer to Peer System. For now, you can write a peer as
public class MyOwnPeer extends Peer
{
//implement few methods!
}
The peers identify each other through IP Multicasting. In a day or two, I hope to write a short tutorial on how to develop a P2P chat application using our library. For now, it runs within private networks only. And does not run across internet!

Also the library at its current stage enables very easy development of Server application! you can write your echo server without having to worry about threading or anything else!
It is as simple as
public class EchoServer extends ServerComponent
{
//implement few methods!
}

We hope to release the library as early as possible.

The echo server sample is shown below!
Isnt' that easy! This is just the very initial stages of development and hopefully the library grows to something really big. The library relies heavily on Object-Oriented Concepts !
// SAMPLE SERVER CODE!!
class EchoServer extends ServerComponent {

public EchoServer(int port) {
super(port);
}

@Override
public void beforeServerStarts() {
System.out.println("Server about to start");
}

@Override
public void onIncomingConnection(Socket socket) {
try {
BufferedReader buff = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
PrintWriter pw = new PrintWriter(socket.getOutputStream());
String temp = "";
while ((temp = buff.readLine()) != null) {
pw.println(temp);
pw.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Override
public void onServerStarted() {
System.out.println("Server Started!");
}

public static void main(String[] args) {
EchoServer my = new EchoServer(1233);
}
}

Wednesday, September 19, 2007

Send Keys in Java or automate repetitive tasks programmatically.

If you have ever programmed in VB, you will definitely know what SendKeys are. You can use send keys function in vb to send in keystrokes to other applications, to be specific to that application which has focus. You can do similar work in Java.

You have send keys like functionality in java.awt.Robot class. You can instantiate a Robot class and then use methods like keyPress(KeyEvent.ENTER), keyRelease, mouseMove, mouseClick, etc.

This is very useful. Like I mentioned in the previous posts, I am running certain tests using Browser Widget. And I am not always infront of the system. And I do get a lot of dialog pop-ups which require a user to manually click OK. I mentioned about wmctrl in the previous posts but I did not get to send keys from wmctrl, so here is what I did.

I used wmctrl to get a list of open windows and specifying -x option to wmctrl would give you even the WM_CLASS and based on this, I use -a option to bring the particular window on top. Then once when the window is on top, I use Robot class to send keys.

There are other good tools like Expect scripts, Devilspie which can automate tasks but I did not have enough time to learn them from scratch. EXPECT is more prominent out there but Devilspie too looked promising.

Saturday, September 15, 2007

Configuring SWT Browser Widget Preferences!

This technique I discovered works on Linux, ie. when SWT Browser uses Mozilla as its underlying browser. It uses JavaXPCOM to connect with Mozilla and does great job doing so. But then the Browser class do not have any options to configure the preferences of the browser. But you can still configure the preferences of the browser!!
Mozilla preferences are stored in a .mozilla directory for each user, in their home directory. Thanks to Dr. Li, that I could find this out. Now if you run a program that uses SWT Browser, you can see a a folder "Eclipse" inside this .mozilla directory.

[Note I am talking about running a Java Program which has SWT Browser, from ECLIPSE, thus the folder name is eclipse. If you run from console, you might have a different foldername(I guess as that of the program name)]
It is in the /home//.mozilla/eclipse directory that the SWT Browser used Mozilla preferences are stored. It is stored in the prefs.js javascript file. You can specify a user prefernces by using user_pref() function. For example, you want a network boosted SWT Browser widget, then may be you can add the following line to prefs.js
user_pref("networking.http.pipelining",true);
Close Eclipse and start again. Now when you launch the program, the browser would use this preference.
Another way is to use "about:config" within your program do the configuration!
For this you can just write a configure() function and use it when you want. The function can be something like
Class ConfigurationWindow
{
public void configure()
{
Display display = new Display();
Shell shell = new Shell(display);

Browser browser = new Browser(shell,SWT.CENTER);

shell.setLayout(new GridLayout());

browser.setUrl("about:config");

shell.open();

while(!shell.isDisposed())
if(!display.readAndDispatch()) display.sleep();

shell.dispose();
display.dispose();
browser.dispose();
}
}

Now you can create new instance of ConfigurationWindow and call configure() which shows the user preferences window, just like the one you get when you type about:config in Mozilla Firefox.
This way one can configure preferences for Swt Browser Widget!

Friday, September 14, 2007

BUG in SWT Browser Widget

I have just discovered a bug in SWT Browser Widget which is used by Eclipse for its internal browser. Just type in http://www.friendster.com/ anyway inside eclipse (some editor inside eclipse). Hold CTRL and click on that link to open Eclipse internal browser. As the page is about to finish loading, Eclipse closes!!
The version I am using is SWT 3.3, the latest, so called stable release.
No idea as of now why this is happening. I guess there is some component inside friendster.com homepage that SWT Browser widget does not like much, and infact it is a VM error!
By the way I am running Fedora Core 7.

Thursday, September 13, 2007

Small Read from file, write to file utility

A Java Class that I wrote for my own use. Just to have ease of access.....
--------------------------------------------------------------------------------------------------
package buddi.thesis;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;

public class DataStore {

private PrintWriter writer=null;
private BufferedReader reader=null;
public DataStore(String input, String output)
{
try {
reader = new BufferedReader(new FileReader(input));
writer = new PrintWriter(new File(output));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

public String getNextItem()
{
if(reader==null)
return null;
String temp;
try {
temp = reader.readLine();
if(temp!=null)
return temp;
} catch (IOException e) { }
return null;
}

public void writeToOutput(String text)
{
if(writer==null)
{
System.out.println("ERROR : COULD NOT WRITE TO OUTPUT!");
return;
}
writer.println(text);
writer.flush();
}

public void close()
{
try {
reader.close();
writer.close();
reader=null;
writer=null;
} catch (IOException e) {
}
}
}

Wednesday, September 12, 2007

Java Program to detect Server side redirections!

As a part of my research work, I wrote this small function in Java which gives you HTTP Response Code and with which we can actually detect server side redirects. The server side redirects have a response code as 302. Well here is the program,

public class NetworkTool {
public static int getResponseCode(String url) {

try {
URL urlItem = new URL(url);
HttpURLConnection con = (HttpURLConnection) urlItem.openConnection();
con.setReadTimeout(1000);
con.setConnectTimeout(5000);
//System.out.println(con.getConnectTimeout());
con.setInstanceFollowRedirects(false);
int res = con.getResponseCode();
return res;
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
catch(Exception ex){//System.out.println("hehe");
}
return -1;
}

public static void main(String[] args)
{
System.out.println(getResponseCode("http://cs.uga.edu/index.htmx"));
System.out.println(getResponseCode("http://buddibuddibuddi.com"));
System.out.println(getResponseCode("http://128.192.1.21"));
}
}

The statements highlighted in bold are important. Otherwise, there are some url for which you get connected to the server but you keep waiting for infinite time for the data to come on the connection. So if we set time-out on read, we don't wait for long and this is especially helpful when you run the tests on huge data.
It took me quite a long time to get the actual code fixed, and then to find out the two statements. So I hope this post would be useful for others too.