320 likes | 462 Views
Lecture08. Reading and Writing Images in Java. Imaging Models of Java. Push Imaging Model Immediate Mode Imaging Model Pull Imaging Model. This is fully implemented in Java Advanced Imaging API. Some parts of this could be seen in java.awt. Push Imaging Model.
E N D
Lecture08 Reading and Writing Images in Java
Imaging Models of Java • Push Imaging Model • Immediate Mode Imaging Model • Pull Imaging Model. This is fully implemented in Java Advanced Imaging API. Some parts of this could be seen in java.awt.
Push Imaging Model • In push imaging model the image data isn’t introduced into the imaging pipeline until it is needed; at which time an object called ImageProducer starts pushing the data into this pipeline. On the other end of this pipeline is an ImageConsumer that must wait for the data to get pushed to it. This model was designed to provide a simple way to load images into applets and applications.
Push Imaging Model • Advantages • It can load and display images incrementally as they become available. • Disadvantages • The image data isn’t collected into an accessible location, making anything more than simple image processing difficult. • The programming interface can be confusing.
The Image Class • It is better to think of the java.awt.image class as a group of resources and methods that provide a means for transferring and inquiring about a collection of image data and not as the collection itself.
Image rendering situations in java • In an applet: // ... URL url; // ... Image img = getImage(url); // first step // ... public void paint(Graphics g) { // ... g.drawImage(img, 0, 0, this); // second step // ... } // ...
Image rendering situations in java • In an application: // ... Image img = Toolkit.getDefaultToolkit().getImage(filename); // ... public void paint(Graphics g) { // ... g.drawImage(img, 0, 0, this); // second step // ... } // ...
Image rendering situations in java • In both cases, the initial step doesn’t start loading the image data, but instead instantiates an Image object that creates the resources necessary to process the image data. • The second method begins image loading, although the method returns immediately regardless of how much of the image is available to display. • The actual loading continues in a separate thread, where an object implementing the java.awt.ImageProducer interface sends image data to an object implementing the java.awt.ImageConsumer interface. • While ImageProducer sends image data into the ImageComsumer, the ImageObserver interface asynchronously receives the status information about the image transfer.
ImageObserver interface • This status information is passed to the ImageObserver interface via the method: public boolean imageUpdate(Image img, int infoFlags, int x, int y, int width, int height) of the ImageObserver class. • Remember the Component class and any decendent of it such as the Applet class, is an ImageObserver. • The default behaviour of the Applet’s imageUpdate method is to repaint the applet whenever new data bits are available.
Introduction to Image I/O API • Java Image I/O package was created to overcome the limitations of reading/writing of formatted images of then Java APIs. Now Java image I/O API is integrated with the core java language. Two useful properties of Java image I/O API: • Plug-ins: The run time Java Vitual Machine (JVM) discovers which image readers/writers are available and what types of image formats they can decode/encode. • Metadata: The non-pixel information about the input images and output images.
Supported Formats • Readers • GIF • JPEG • PNG • Writers • JPEG • PNG
Image Readers • With the Java2D package, the input images are converted to Image objects using the getImage methods of the Applet class and the Toolkit class. • With Image I/O package, input images are converted to BufferedImages using the read methods of the javax.imageio.ImageReader class. • Generally you have more than one ImageReader subclasses.
javax.imageio.ImageReaderSpis • The initial step in reading an image is to choose an ImageReader that can decode the format of the image of interest. This is done by providing information about that image’s format to a set of ImageReader service providers javax.imageio.ImageReaderSpis. This information can be: • Image file suffix • Image MIME type • Image format • Image data
MIME type • Multipurpose Internet Mail Extensions. • Examples: Extension Type Use jpg image/jpeg JPEG image jpeg image/jpeg JPEG image mpg video/mpeg MPEG video au audio/basic ULAW audio data avi video/x-msvideo Microsoft video • For details check http://www.iana.org/assignments/media-types/
Reading and Writing Basics • One of the ImageReaders whose service provider responds positively will be choosen to convert the image into a BufferedImage. • While some ImageReaders are part of Java SDK, the rest can be downloaded from third party vendors, freeware, and shareware sites. • If no appropriate ImageReader available, then one can be written. • The process of writing images is simmilar and has the corresponding classes ImageWriters and javax.imageio.ImageWriterSpis.
ImageIO class • The ImageIO class contains static methods that are mainly used for locating ImageReaders and ImageWriters. To find out plugins by format names, you can use: static String[] getReaderFormatNames() static String[] getWriterFormatNames() • To find out plugins by MIME types: static String[] getReaderMIMETypes() static String[] getWriterMIMETypes()
ImageIO class • In order to find out ImageReaders for a particular image the following static methods of ImageIO class can be used: static Iterator getImageReadersByFormatName(String formatName) static Iterator getImageReadersByMIMEType(String MIMEType) static Iterator getImageReadersBySuffix(String fileSuffix) • The following method find ImageReaders by examining the object representing the image input stream ( of the class javax.imageio.stream.ImageInputStream): static Iterator getImageReaders(Object input)
ImageInputStream • The ImageInputStreams can be created as follows: URL url = new URL(imageURL); ImageInputStream iis = ImageIO.createImageInputStream(url.openStream()); or Socket s = new Socket(imageHost, imagePort); ImageInputStream iis = ImageIO.createImageInputStream(s.getInputStream()); or FileInputStream fis = new FileInputStream(imageFileName); ImageInputStream iis = ImageIO.createImageInputStream(fis); • Note that the most image formats begin with something called a magic number, which is the part of ImageInputStream that most ImageReaderSpis use to decide whether they can decode an image format.
ImageWriter • For a known ImageWriter the corresponding ImageReaders can be found by: static ImageReader getImageReader(ImageWriter writer) • The corresponding ImageWriter static methods of ImageIO are: static Iterator getImageWritersByFormatName(String formatName) static Iterator getImageWritersByMIMEType(String MIMEType) static Iterator getImageWritersBySuffix(String fileSuffix) static Iterator getImageWriters(ImageTypeSpecifier type, string format) static ImageWriter getImageWriter(ImageReader reader) • The javax.imageio.ImageTypeSpecifier is a class that specifies ColorModel/SampleModel combination.
Using The ImageReader • An application need to do two things in order to interact with an ImageReader: • provide it with an input source • Use it to read the source image(s) • The following method of ImageReader is used to provide it with an input source: public void setInput(Object input, boolean seekForwardOnly) where input is usually an ImageInputStream and seekForwardOnly parameter is used to specify whether an application can go backwards in the input stream.
Using The ImageReader • Once an input source is defined either of the following methods can be used to read images: public void read(int imageIndex) public void read(int imageIndex, ImageReadParam param) where imageIndex is the index of the image that will be read and param parameter provides control over how this image is to be read.
Using The ImageReader • The number of images can be obtained using the method: public int getNumImages(boolean allowSearch) where the allowSearch parameter specifies whether you want the entire ImageInputStream examined to determine the number of available images. If allowSearch parameter is false, the number of images is returned only if it is immediately available otherwise -1 is returned.
Example URL url; try { url = new URL(inputURL); } catch (MalformedURLException mue) { // Process the exception } ImageInputStream iis; try { iis = ImageIO.createImageInputStream(url.openStream()); } catch (IIOException iioe) { // Process the exception } catch (IOException ioe) { // Process the exception }
Example Iterator readers = ImageIO.getImageReaders(iis); ImageReader reader; if (readers.hasNext()) { reader = (ImageReader) readers.next(); reader.setInput(iis,true); } if (reader == null) { // Process the error message }
Example BufferedImage bi; int imageIndex = 0; try { while (bi = reader.read(imageIndex++)) { // process bi here } } catch (IOException ioe) { // Process the exception } catch (IndexOutOfBoundsException iobe) { /* all the images have been read */ } // ...
Using The ImageWriter • As with ImageReader, an application does two things when interacting with an ImageWrier: • provide it with an output source • Use it to write the image(s) into the output source • The setOutput method of ImageWriter is used to define an output source: public void setOutput(Object output) where output is typically an ImageOutputStream
ImageOutputStream Socket s = new Socket(imageHost, imagePort); ImageOutputStream ios = ImageIO.createImageOutputStream( s.getOutputStream()); or FileOutputStream fos = new FileOutputStream(imageFileName); ImageOutputStream ios = ImageIO.createOutputStream(fos);
Using Writers The main write method is: public void write(IIOMetadata streamMetadata, IIOImage iioImage, ImageWriteParam param) where streamMetadata can be set to null, if there is no stream metadata. javax.imageio.IIOImage is a container class used for holding the following information: • The image • The image’s associated thumbnail images, represented as java.util.List of BufferedImages. • If the image format does not support thumbnail images this can be set to null. • The image’s metadata. If the image format does not support metadata this can be set to null.
Simple Image Reading • The ImageIO class has the following methods: • public static BufferedImage read(File input) throws IIOException • public static BufferedImage read(URL input) throws IIOException • public static BufferedImage read(InputStream stream) throws IIOException • public static BufferedImage read(ImageInputStream stream) throws IIOException
Example: Reading an Image public static BufferedImage readAsBufferedImage(String filename) { try { BufferedImage img = ImageIO.read(new File(filename)); return img; } catch (Exception e) { e.printStackTrace(); return null; } }
Simple Image Writing • The ImageIO has following methods. public static boolean write(RenderedImage im, String formatName, File output) throws IIOException public static boolean write(RenderedImage im, String formatName, OutputStream output) throws IIOException public ststic boolean write(RenderedImage im, String formatname ImageOutputStream output) throws IIOException
Example: Writing an Image public void save(BufferedImage image, String filename) { try { ImageIO.write((RenderedImage) image,"jpg", new File(filename)); } catch (exception e) { // Process the exception } }