Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Monday, October 18, 2010

How to Print from Java (JPS) - javax.print Package

javax.print package is available in JDKs 1.4 and above. Formerly Java AWT printing API was used to perform basic printing and now it is enhanced with advanced options like printer service discovery, in javax.print API.

I am posting a simple example showing how to perform a basic print using javax.print API.

import java.io.*;
import javax.print.*;

public class PrintTest {
 public static void main(String[] args) throws IOException {
  //we are going to print "printtest.txt" file which is inside working directory
  File file = new File("printtest.txt");
  InputStream is = new BufferedInputStream(new FileInputStream(file));
  
  //Discover the default print service. If you call PrintServiceLookup.lookupPrintServices
  //then it will return an array of print services available and you can choose a
  //printer from them
  PrintService service = PrintServiceLookup.lookupDefaultPrintService();
  
  //Doc flavor specifies the output format of the file (Mime type + Char encoding)
  //You can retrieve doc flavors supported by the printer, like this
  //DocFlavor [] supportedFlavors = service.getSupportedDocFlavors();
  DocFlavor flavor = DocFlavor.INPUT_STREAM.TEXT_PLAIN_US_ASCII;  
  
  
  // Create the print job
  DocPrintJob job = service.createPrintJob();
  //Create the Doc. You can pass set of attributes(type of PrintRequestAttributeSet) as the 
  //3rd parameter specifying the page setup, orientation, no. of copies, etc instead of null. 
  Doc doc = new SimpleDoc(is, flavor, null);

  //Order to print, (can pass attributes instead of null)
  try {
   job.print(doc, null);
  } catch (PrintException e) {
   e.printStackTrace();
  }  

  //DocPrintJob.print() is not guaranteed to be synchronous. So it's better to wait on completion
  //of the print job before closing the stream. (See the link below)
  is.close();
  System.out.println("Printing done....");
 }

}

This example shows how to create a Print job watcher. You can create an object from PrintJobWatcher in your PrintTest class and call waitForDone() before closing the stream.

You can find documentation on javax.print API here.

The DocFlavor I have used in this example (INPUT_STREAM.TEXT_PLAIN_US_ASCII) wont work on Windows. The PrintService doesn't discover this flavor as a supported one for some reason. Yes, this Java Print Service facility is still buggy (in JDK 1.6). It is weird that we can't print ASCII formatted files while we can print any JPEG or PNG.  I used INPUT_STREAM.AUTOSENSE flavor which uses mime type "application/octet-stream", to print on Windows. Then the printer will print just the octets coming from the stream.However it works fine.

Saturday, February 27, 2010

How to merge multiple images into one image - Java ImageIO

My previous post shows how to split an image into chunks. Now let's see how to merge multiple images into one image. Say we need to concatenate following four image chunks. I got these chunks by splitting the image in the right hand side, using the image splitter.

















Following code shows how to concatenate the image chunks above into one image.
int rows = 2;   //we assume the no. of rows and cols are known and each chunk has equal width and height
        int cols = 2;
        int chunks = rows * cols;

        int chunkWidth, chunkHeight;
        int type;
        //fetching image files
        File[] imgFiles = new File[chunks];
        for (int i = 0; i < chunks; i++) {
            imgFiles[i] = new File("archi" + i + ".jpg");
        }

       //creating a bufferd image array from image files
        BufferedImage[] buffImages = new BufferedImage[chunks];
        for (int i = 0; i < chunks; i++) {
            buffImages[i] = ImageIO.read(imgFiles[i]);
        }
        type = buffImages[0].getType();
        chunkWidth = buffImages[0].getWidth();
        chunkHeight = buffImages[0].getHeight();

        //Initializing the final image
        BufferedImage finalImg = new BufferedImage(chunkWidth*cols, chunkHeight*rows, type);

        int num = 0;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                finalImg.createGraphics().drawImage(buffImages[num], chunkWidth * j, chunkHeight * i, null);
                num++;
            }
        }
        System.out.println("Image concatenated.....");
        ImageIO.write(finalImg, "jpeg", new File("finalImg.jpg"));

Wednesday, February 24, 2010

How to Split an Image into Chunks - Java ImageIO

Image splitting and concatenating and other image manipulation techniques are important in parallel computing. Say we are receiving small chunks of an Image which is being manipulated parallely. In such scenarios, we need to concatenate those chunks together and vice versa.

There is a pretty straight forward way to split an image using Java imageio package. Say you need to split following image into several chunks (you should decide the no. of rows and columns needed).















Now I am going to split this image into 16 chunks (4 rows and 4 columns). I have shown the code snippet below.

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.awt.*;

public class ImageSplitTest {
    public static void main(String[] args) throws IOException {

        File file = new File("bear.jpg"); // I have bear.jpg in my working directory
        FileInputStream fis = new FileInputStream(file);
        BufferedImage image = ImageIO.read(fis); //reading the image file

        int rows = 4; //You should decide the values for rows and cols variables
        int cols = 4;
        int chunks = rows * cols;

        int chunkWidth = image.getWidth() / cols; // determines the chunk width and height
        int chunkHeight = image.getHeight() / rows;
        int count = 0;
        BufferedImage imgs[] = new BufferedImage[chunks]; //Image array to hold image chunks
        for (int x = 0; x < rows; x++) {
            for (int y = 0; y < cols; y++) {
                //Initialize the image array with image chunks
                imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType());

                // draws the image chunk
                Graphics2D gr = imgs[count++].createGraphics();
                gr.drawImage(image, 0, 0, chunkWidth, chunkHeight, chunkWidth * y, chunkHeight * x, chunkWidth * y + chunkWidth, chunkHeight * x + chunkHeight, null);
                gr.dispose();
            }
        }
        System.out.println("Splitting done");

        //writing mini images into image files
        for (int i = 0; i < imgs.length; i++) {
            ImageIO.write(imgs[i], "jpg", new File("img" + i + ".jpg"));
        }
        System.out.println("Mini images created");
    }
}

 Parameter list of "drawImage()" (See line 28)
--   image - The source image
--   0, 0  - X,Y coordinates of the 1st corner of destination image
--   chunkWidth, chunkHeight - X,Y coordinates of the opposite corner of destination image 
--   chunkWidth * y, chunkHeight * x - X,Y coordinates of the 1st corner of source image block
--   chunkWidth * y + chunkWidth, chunkHeight * x + chunkHeight - X,Y coordinates of 
             the opposite corner of source image block

Now you'll see 16 image chunks formed in your working directory.


Tuesday, January 12, 2010

How to Write a Custom Class Loader to Load Classes from a Jar

A custom class loader is needed when the developer needs to load classes from some custom repositories, to implement hot deployment features and to allow unloading of classes.

According to Java2 class loading system, a custom class loader should subclass java.lang.ClassLoader and overrride findClass() method which is responsible for loading the class bytes and returning a defined class.

Following code is a custom class loader which loads classes from jars, inside the directory called "jar".

public class JarClassLoader extends ClassLoader {
    private String jarFile = "jar/test.jar"; //Path to the jar file
    private Hashtable classes = new Hashtable(); //used to cache already defined classes

    public JarClassLoader() {
        super(JarClassLoader.class.getClassLoader()); //calls the parent class loader's constructor
    }

    public Class loadClass(String className) throws ClassNotFoundException {
        return findClass(className);
    }

    public Class findClass(String className) {
        byte classByte[];
        Class result = null;

        result = (Class) classes.get(className); //checks in cached classes
        if (result != null) {
            return result;
        }

        try {
            return findSystemClass(className);
        } catch (Exception e) {
        }

        try {
            JarFile jar = new JarFile(jarFile);
            JarEntry entry = jar.getJarEntry(className + ".class");
            InputStream is = jar.getInputStream(entry);
            ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
            int nextValue = is.read();
            while (-1 != nextValue) {
                byteStream.write(nextValue);
                nextValue = is.read();
            }

            classByte = byteStream.toByteArray();
            result = defineClass(className, classByte, 0, classByte.length, null);
            classes.put(className, result);
            return result;
        } catch (Exception e) {
            return null;
        }
    }

}

This code can be improved to
* Load classes from any jar inside the directory
* Dynamically pick up classes if the jar is updated (by keeping a modified time field)

Saturday, November 01, 2008

How to Replace Strings in Java - Using java.util.regex package

Replacing a charater in a String is just a matter of adding a one line to the code.

originalString.replace(oldChar, newChar)

ex.
String originalString = "This/is/my/string";
System.out.println(originalString.replace('/', '|'));
Then the output will be "This|is|my|string"


Anyway how can we replace a character or number of characters(a substring) with another string. This can be done using the regex package in Java.


If we need to replace "my" with "your" we can do it in the following way.
import java.util.regex.*;  

String originalString = "This is my string";
Pattern pat = Pattern.compile("my"); 
Matcher mat = pat.matcher(originalString);
System.out.println(mat.replaceAll("your")); 
mat.reset();
The output will be "This is your string"

Monday, July 28, 2008

Extracting the Text from XML Documents for Indexing Purposes

In the process of creating a Lucene index for content searching I had to index XML document without XML tags. In simple terms I had to extract every text node from the document. I used the SAX API in doing this and it was just a matter of writing an event handler for character data. The following piece of code shows the way to do it.
final StringBuffer sb = new StringBuffer();

try{
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();

DefaultHandler handler = new DefaultHandler() {
//Other event handlers (for startElement and endElement) also can be implemented similarly
public void characters(char ch[], int start, int length)
throws SAXException {
    sb.append(new String(ch, start, length));
}};

saxParser.parse("fileName.xml", handler);
System.out.println(sb.toString());
}catch(Exception e){
e.printStackTrace();
}

This can be done using the StAX API too. But these libs a are only available in Java 1.6 onwards. The following code works with Java 1.6. However, you may be able to use the Woodstock parser without changing the code.
try {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
InputStream in = new FileInputStream("fileName.xml");
XMLEventReader eventReader = inputFactory.createXMLEventReader(in);
StringBuffer bf = new StringBuffer();

while (eventReader.hasNext()) {
    XMLEvent event = eventReader.nextEvent();
    //here we only consider the event startElement and get the text inside that element
    if(event.isStartElement()){
    event = eventReader.nextEvent();  
    bf.append(event.asCharacters().getData()+" ");
    }
}

System.out.println(bf.toString());

}catch(Exception e){

}
Related Posts with Thumbnails