Opening an Image File


All the user needs to do to open an image file is to use the File menu's Open… item. When the user selects that item, the actionPerformed method is called. Then, after making sure the Open… item was selected, the code sets the dialog object's mode to FileDialog.LOAD and makes the dialog box visible with the dialog.setVisible(true) call:

 public void actionPerformed(ActionEvent event) {     if(event.getSource() == menuitem1){         dialog.setMode(FileDialog.LOAD);         dialog.setVisible(true);     .     .     . 

Setting the File dialog box's mode to FileDialog.LOAD (the only other option is FileDialog.SAVE) makes the dialog box display the File Open dialog box you see in Figure 3.2.

Figure 3.2. Opening a file.


You can see the significant methods of the FileDialog class in Table 3.1.

Table 3.1. The Significant Methods of the java.awt.FileDialog Class

Method

Does This

String getDirectory()

Returns the directory selected by the user

String getFile()

Returns the file selected by the user

FilenameFilter getFilenameFilter()

Returns the filename filter used by this File dialog box

int getMode()

Returns the dialog box's mode, which sets whether this File dialog box is to be used in reading a file or saving a file

void setDirectory(String dir)

Sets the directory used by this File dialog box when it starts to the given directory

void setFile(String file)

Sets the selected file used by this File dialog box to the given file

void setFilenameFilter(FilenameFilter filter)

Sets the filename filter for the dialog box to the given filter

void setMode(int mode)

Specifies the mode of the File dialog box, either reading or writing


If the user selects a file to open, the dialog box's getFile method will return the filename, and the getdirectory method will return the directory the file is in. Opening a file is a sensitive operation, so everything's enclosed in a try/catch block here. The code creates a File object corresponding to the image file the user wants to open as the first stage in actually opening that file:

 public void actionPerformed(ActionEvent event) { if(event.getSource() == menuitem1){     dialog.setMode(FileDialog.LOAD);     dialog.setVisible(true);     try{         if(!dialog.getFile().equals("")){             File input = new File(dialog.getDirectory()                 + dialog.getFile());             .             .             .     }     catch(Exception e){         System.out.println(e.getMessage());     }         .         .         . } 

You can see the significant methods of the File class in Table 3.2.

Table 3.2. The Significant Methods of the java.io.File Class

Method

Does This

boolean canRead()

Returns true if you can read the file specified by this File object

boolean canWrite()

Returns true if you can modify the file specified by this File object

boolean createNewFile()

Creates a new, empty file corresponding to this file and pathif (and only if) that file does not already exist

boolean delete()

Deletes the file or directory specified by this File object

boolean exists()

Returns true if the file or directory specified by this File object exists

File getAbsoluteFile()

Returns the absolute form of this file's path and name

String getAbsolutePath()

Returns the absolute form of this file's path

String getName()

Returns the name of the file (or directory) specified by this File object

String getPath()

Returns the path of the file (or directory) specified by this File object

boolean isAbsolute()

Returns TRue if the file's pathname, as stored in this File object, is absolute

boolean isDirectory()

Returns true if the file referred to by this File object is a directory

boolean isFile()

Returns true if the file referred to by this File object is a standard file

boolean isHidden()

Returns TRue if the file referred to by this File object is a hidden file

long lastModified()

Returns the time at which the file was last modified

long length()

Returns the length of the file

boolean mkdir()

Makes a directory corresponding to the name and path given in this File object

boolean renameTo(File dest)

Renames the file to the name and path given by the File object you pass

boolean setLastModified(long time)

Sets the last-modified time of this file or directory

boolean setReadOnly()

Makes the file (or directory) given by this File object read-only

URI toURI()

Returns a URI that represents the file given by this File object

URL toURL()

Returns a URL that represents the file given by this File object


To read in the image file, the application uses the relatively new Java ImageIO class. All you have to do is to pass the File object to the ImageIO class's read method, which reads in the file (unless there's an error, which will be caught in the catch block) and returns a BufferedImage object:

 public void actionPerformed(ActionEvent event) {     if(event.getSource() == menuitem1){         dialog.setMode(FileDialog.LOAD);         dialog.setVisible(true);         try{             if(!dialog.getFile().equals("")){                 File input = new File(dialog.getDirectory()                     + dialog.getFile());                 bufferedImage = ImageIO.read(input);                 .                 .                 .         }         catch(Exception e){             System.out.println(e.getMessage());         }             .             .             .     } 

You can see the significant methods of the ImageIO class in Table 3.3.

Table 3.3. The Significant Methods of the javax.imageio.ImageIO Class

Method

Does This

static String[] getReaderFormatNames()

Returns an array holding all the format names the current readers can read

static String[] getReaderMIMETypes()

Returns an array holding all the MIME types the current readers can read

static String[] getWriterFormatNames()

Returns an array holding all the format names the current writers can write

static String[] getWriterMIMETypes()

Returns an array holding all the MIME types the current writers can write

static BufferedImage read(File input)

Reads in a file as specified by the File object and returns a BufferedImage object

static BufferedImage read(ImageInputStream stream)

Reads in a file as specified by the ImageInputStream object and returns a BufferedImage object

static BufferedImage read(InputStream input)

Reads in a file as specified by the InputStream object and returns a BufferedImage object

static BufferedImage read(URL input)

Reads in a file as specified by the URL object and returns a BufferedImage object

 static boolean write(RenderedImage im, String formatName, File output) 

Writes an image using a RenderedImage object, a format name string, and a File object

 static boolean write(RenderedImage im, String formatName, ImageOutputStream output) 

Writes an image using a RenderedImage object, a format name string, and an ImageOutputStream object

 static boolean write(RenderedImage im, String formatName, OutputStream output) 

Writes an image using a RenderedImage object, a format name string, and an OutputStream object


Why does the Graphicizer use BufferedImage objects instead of Image objects? Primarily because the ImageIO class uses them instead of Image objectsand the ImageIO class gives you the functionality you need in an application such as Graphicizer. Using that class, you can read in files in various formats (GIF, PNG, and JPEG) and save them in various formats (PNG and JPEG).

Using the Toolkit class's image-handling methods you saw in the Aquarium and Slapshot! applications, you can only read in files; not only can you not change their format when you save them, you can't even save them in the first place. You can see the significant methods of the BufferedImage class in Table 3.4.

Table 3.4. The Significant Methods of the java.awt.image.BufferedImage Class

Method

Does This

WritableRaster copyData(WritableRaster outRaster)

Copies a rectangular region of the BufferedImage to the given WritableRaster

Graphics2D createGraphics()

Returns a new Graphics2D object, which you can use to draw in this BufferedImage

 ImageCapabilities getCapabilities (GraphicsConfiguration gc) 

Returns the imaging capabilities of this BufferedImage object

ColorModel getColorModel()

Returns the color model used by this BufferedImage object

Raster getData(Rectangle rect)

Returns a region of the BufferedImage object

Graphics getGraphics()

Returns a Graphics2D object, which you can use to draw in this BufferedImage

int getHeight()

Returns the height of the BufferedImage

int getHeight(ImageObserver observer)

Returns the height of the image in this BufferedImage object

int getMinX()

Returns the minimum X coordinate of the image in this BufferedImage object

int getMinY()

Returns the minimum Y coordinate of the image in this BufferedImage object

WritableRaster getRaster()

Returns the WritableRaster object used by this BufferedImage object

int getRGB(int x, int y)

Returns a pixel specified by the X and Y coordinates using the default RGB color model (TYPE_INT_ARGB) and default sRGB colorspace

 int[] getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize) 

Returns an array of pixels using the default RGB color model (TYPE_INT_ARGB) and default sRGB colorspace

BufferedImage getSubimage(int x, int y, int w, int h)

Returns a section of the image specified by the given rectangular region

int getTransparency()

Returns the transparency setting of this BufferedImage object

int getType()

Returns the type of the image

int getWidth()

Returns the width of the image contained in this BufferedImage object

int getWidth(ImageObserver observer)

Returns the width of the image contained in this BufferedImage object using an ImageObserver

boolean isAlphaPremultiplied()

Returns true if the alpha values for this image have been premultiplied

void setData(Raster r)

Sets a rectangular region of the image using the given Raster object

void setRGB(int x, int y, int rgb)

Sets a pixel in this BufferedImage to the given RGB value

 void setRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize) 

Sets a pixel array in this BufferedImage to the given RGB value


REAL-WORLD SCENARIO: Why Can't You Write GIF Files?

The ImageIO class is all about reading in images and writing them out again. You can read in GIF, PNG, and JPEG files, and write out PNG and JPEG files. What's missing from this equation?

By default, you can't use the ImageIO class to write GIF files. Why is that? It turns out that the people responsible for the GIF format began requiring software that uses some patented aspects of GIF formatting to have a license, and that's quite probably the reason.

Entering widespread use in about 1987, the GIF (Graphics Interchange Format) image format became very popular. At the end of 1994, however, CompuServe Inc. and Unisys Corporation said that developers would have to pay a license fee to be able to use technology that had been patented by Unisys supporting the GIF format.

Among developers, this caused quite a controversy. Programmers whose software could use GIF files were unsure of their legal standing (note, incidentally, that this sidebar is not intended as a substitute for legal advice!), and loud discussions among developers ensued.

People whose software relied on GIF formatting had to deal with this issue, and in time, some developers began to move away from that format.

Some of the patents have begun to expire now (see http://www.unisys.com/about__unisys/lzw), but a number of developers are still wary. Although Sun hasn't said so, this is probably the reason why you can't write GIF format files with the ImageIO class by default (various third parties have provided plug-ins that let you do so). You can determine which readable and writeable formats can be used by calling the ImageIO.getReaderFormatNames and ImageIO.getWriterFormatNames methods.

Alternatives, such as Portable Network Graphics (PNG) format, appeared in the web community and are becoming increasingly popular. Personally, I like the PNG format and use it extensively. It's readable by all the major browsers, and it doesn't suffer from the image quality losses that most JPEG files do. If you want a high-quality way to store images, my advice is to use PNG format; you're going to see more and more of it in the coming years.


After the image has been read in and is stored in the BufferedImage object, the code resizes its window in order to display the new image, while still maintaining a minimum size. You can determine the size of the image with the BufferedImage class's getWidth and getHeight methods, so here's what resizing the window to match the image looks like:

 public void actionPerformed(ActionEvent event) {     if(event.getSource() == menuitem1){         dialog.setMode(FileDialog.LOAD);         dialog.setVisible(true);         try{             if(!dialog.getFile().equals("")){                 File input = new File(dialog.getDirectory()                     + dialog.getFile());                 bufferedImage = ImageIO.read(input);                 setSize(getInsets().left + getInsets().right +                     Math.max(400, bufferedImage.getWidth() + 60),                     getInsets().top + getInsets().bottom +                     Math.max(340, bufferedImage.getHeight() + 60));                 .                 .                 .     } 

You also have to move the buttons to match and then repaint the entire window so the loaded image will appear; here's what that looks like in the code:

 public void actionPerformed(ActionEvent event) {     if(event.getSource() == menuitem1){     .     .     .         try{             if(!dialog.getFile().equals("")){                 File input = new File(dialog.getDirectory()                     + dialog.getFile());                 bufferedImage = ImageIO.read(input);                 setSize(getInsets().left + getInsets().right +                     Math.max(400, bufferedImage.getWidth() + 60),                     getInsets().top + getInsets().bottom +                     Math.max(340, bufferedImage.getHeight() + 60));                 button1.setBounds(30, getHeight() - 30, 60, 20);                 button2.setBounds(100, getHeight() - 30, 60, 20);                 button3.setBounds(170, getHeight() - 30, 60, 20);                 button4.setBounds(240, getHeight() - 30, 60, 20);                 button5.setBounds(310, getHeight() - 30, 60, 20);             }         }         catch(Exception e){             System.out.println(e.getMessage());         }         repaint();     } 

To actually paint the image, Graphicizer will overload the Frame's paint method, coming up next.



    Java After Hours(c) 10 Projects You'll Never Do at Work
    Java After Hours: 10 Projects Youll Never Do at Work
    ISBN: 0672327473
    EAN: 2147483647
    Year: 2006
    Pages: 128

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net