QuickTime offers many
components whose job is to import from
and export to different graphics formats. As you might expect, these
components are wrapped by classes called
GraphicsImporter
and GraphicsExporter
.
The GraphicImportExport
example application (shown
in Example 4-3) uses both of these classes to
illustrate the dynamic lookup of importers and exporters.
Example 4-3. Graphics import and export
package com.oreilly.qtjnotebook.ch04; import quicktime.*; import quicktime.io.*; import quicktime.std.*; import quicktime.std.comp.*; import quicktime.std.image.*; import quicktime.app.view.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.Vector; import java.io.*; import com.oreilly.qtjnotebook.ch01.QTSessionCheck; public class GraphicImportExport extends Object { Button exportButton; Frame frame; GraphicsImporter importer; static final int[ ] imagetypes = { StdQTConstants.kQTFileTypeQuickTimeImage}; /* other interesting values: StdQTConstants.kQTFileTypeGIF, StdQTConstants.kQTFileTypeJPEG, StdQTConstants4.kQTFileTypePNG, StdQTConstants4.kQTFileTypeTIFF StdQTConstants.kQTFileTypeMacPaint, StdQTConstants.kQTFileTypePhotoShop, StdQTConstants.kQTFileTypePICS, StdQTConstants.kQTFileTypePicture, */ public static void main (String[ ] args) { new GraphicImportExport( ); } public GraphicImportExport( ) { try { QTSessionCheck.check( ); QTFile inFile = QTFile.standardGetFilePreview (imagetypes); importer = new GraphicsImporter (inFile); // put image onscreen QTComponent qtc = QTFactory.makeQTComponent (importer); java.awt.Component c = qtc.asComponent( ); frame = new Frame ("Imported image"); frame.setLayout (new BorderLayout( )); frame.add (c, BorderLayout.CENTER); exportButton = new Button ("Export"); exportButton.addActionListener (new ActionListener( ) { public void actionPerformed (ActionEvent ae) { try { doExport( ); } catch (QTException qte) { qte.printStackTrace( ); } } }); frame.add (exportButton, BorderLayout.SOUTH); frame.pack( ); frame.setVisible(true); } catch (QTException qte) { qte.printStackTrace( ); } } public void doExport( ) throws QTException { // build list of GraphicExporters Vector choices = new Vector( ); ComponentDescription cd = new ComponentDescription ( StdQTConstants.graphicsExporterComponentType); ComponentIdentifier ci = null; while ( (ci = ComponentIdentifier.find(ci, cd)) != null) { choices.add (new ExportChoice (ci.getInfo( ).getName( ), ci.getInfo( ).getSubType( ))); } // offer a choice of movie exporters JComboBox exportCombo = new JComboBox (choices); JOptionPane.showMessageDialog (frame, exportCombo, "Choose exporter", JOptionPane.PLAIN_MESSAGE); ExportChoice choice = (ExportChoice) exportCombo.getSelectedItem( ); System.out.println ("chose " + choice.name); // build a GE, wire up to the GraphicsImporter GraphicsExporter exporter = new GraphicsExporter (choice.subtype); exporter.setInputGraphicsImporter (importer); // ask for destination, settings FileDialog fd = new FileDialog (frame, "Save As", FileDialog.SAVE); fd.setVisible(true); String filename = fd.getFile( ); if (filename.indexOf('.') = = -1) filename = filename + "." + exporter.getDefaultFileNameExtension( ); File file = new File (fd.getDirectory( ), filename); exporter.setOutputFile (new QTFile(file)); exporter.requestSettings( ); // export exporter.doExport( ); // need to explicitly quit (since awt is running) System.exit(0); } public class ExportChoice { String name; int subtype; public ExportChoice (String n, int st) { name = n; subtype = st; } public String toString( ) { return name; } } }
When run, the program shows a dialog to select a graphic to be imported. On Windows, the “file type” in this dialog is QuickTime Image. Once an image is selected, it appears in a window with an “export” button. When the user clicks the button, she is asked for an export type, as shown in Figure 4-6.
Note
GraphicsImporter and GraphicsExporter are in quicktime.std.image, not quicktime.std.qtcomponents like most other components.
After this, the program displays a configuration dialog specific to the type of exporter selected—at a minimum, this dialog usually offers a choice of color depths (256 colors, 256 grays, millions of colors, etc.). Next, a save dialog requests the location of the exported file. Once approved, the program converts the image to the specified format and saves it to the supplied location.
Notice the QTFile.standardGetFilePreview()
. This shows a file-open dialog and
takes an array of up to four int
s, representing
FOUR_CHAR_CODE
s of various file format
constants, which are used as a filter of what file types to make
selectable. You can use kQTFileTypeQuickTimeImage
as a convenient wildcard that matches any kind of image QuickTime can
open, though it seems to work only on Windows (on the Mac, any file
can be selected).
Tip
If you want to specify formats, interesting constants in
StdQTConstants
include kQTFileTypeGIF
,
kQTFileTypeJPEG
, and
kQTFileTypePhotoShop
. The
StdQTConstants4
class adds similarly named constants
for PNG and TIFF. Unfortunately, you can send only four.
Given a file, you can construct a
GraphicsImporter
object to load it into QuickTime. To put
the imported image on-screen, pass the importer to
QTFactory.makeQTComponent()
, which returns a
QTComponent
that you can either cast to an AWT
Component
or, to be type-safe, convert with the
asComponent( )
method.
Warning
java.awt
and quicktime.std.comp
both define a class called
Component
. If you’re casually
import
ing every class from these packages,
you’re probably headed for a compile-time error.
You’ll have to make your imports more selective or
use a fully qualified class name for one of the
Component
s, like this example does.
To export an image to another format, you can search for graphics
exporter subtypes by creating a
ComponentDescription
template to match components of the
graphicsExporterComponentType
. In the example, the
names of matching components are shown in a
JComboBox
. With a subtype selected, create the
GraphicsExporter
by passing the subtype to its
constructor.
A GraphicsExporter
needs to be wired up to some
kind of source image. With a GraphicsImporter
, you
wire the two together with setInputGraphicsImporter()
. The exporter also needs a destination. If
writing to a file (as opposed to, say, memory), you set this with
setOutputFile( )
—just to be safe,
it’s wise to sanity-check the user-provided filename
extension against the value returned by the
exporter’s getDefaultFileNameExtension()
.
The user probably wants some say in the color depth, image quality,
and other settings for the export, a dialog for which is provided
with a requestSettings()
.
After all that, you finally can do the export
with...doExport( )
.
...other sources for the export? The Javadoc for
GraphicsExporter
shows a bunch of
setInputXXX( )
methods. True enough, and in the
next chapter, we’ll explore some of these, including
Pict
s, QDGraphics
, and
PixMap
s.
And what about setting export parameters
programmatically? QTJ exposes some methods that could be used instead
of the user dialog, such as setDepth()
and
setCompressionMethod( )
. One interesting method,
setTargetDataSize( )
, lets exporters with a
“quality” option (like JPEG) find a
value that will result in a file of the given size in
bytes.
Get QuickTime for Java: A Developer's Notebook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.