Using QuickTime


QuickTime can be a very imposing API. Often it can be difficult to sift through the many services that QuickTime provides to find the functionality you are interested in. Fortunately, understanding how to import and export images with QuickTime only requires a small number of easily understood routines. This is the functionality in QuickTime that this chapter focuses on.

Import Image Example

QuickTime is a component-based software system. The power of QuickTime comes from having a large number of software components that understand a variety of media formats. To import images, your application must select a graphics import component from the set of components that make up QuickTime and then ask that component to read the image data for you.

An interesting advantage of the QuickTime system is the fact that enterprising software developers can create their own graphics components, including image importers, and extend the system with them. Because all graphics import components can be treated uniformly, if your application understands how to use read images with QuickTime, it can take advantage of all the supported image file types that QuickTime understands.

To use a component, your application must first indicate to the QuickTime library where the image data resides. To do that, the application must first create an entity called a DataRef. A DataRef is little more than a block of memory, a handle, that describes the location of the image data. The type of information contained in the DataRef depends on where the image data lives. If the computer should read the data from a file, the DataRef will contain some kind of file reference (an FSRef, an FSSpec, a URL, or something else). If the data is to be taken from memory, then the DataRef will contain the raw image data itself. The QuickTime API includes a number of routines that help you create DataRefs from popular sources. This example takes the image data from a file and will use the routine QTNewDataReferenceFromFSRef.

A DataRef is usually associated with a type code that indicates what kind of information it contains. The type of the data ref is a 32-bit integer (a four character code) commonly called an OSType. For example, if the DataRef contains an alias handle that points to a file, the type code associated with the DataRef will be 'alis'.

After creating the DataRef, your application must select an appropriate graphics import component for the image data. If you know the data format of your image, you can ask QuickTime to create an import component that understands that format. For example, if you know that your image data is in PNG format, you might use the OpenADefaultComponent routine to create a PNG importer:

OpenADefaultComponent( GraphicsImporterComponentType,     kQTFileTypePNG, importer); 


Most image file formats have distinguishing features that make it easy for the computer to examine the data and determine if it is in a particular format. The most convenient way to select a graphics importer from QuickTime is to use the routine GetGraphicsImporterForDataRef. When you call this routine, the computer traverses the list of all registered graphics importers and asks each to try and determine whether or not it can decode the image data. If it finds an importer that claims to be able to read the data, it will return that component to your application.

In some cases, the computer may not be able to determine what kind of importer to use based on the image data itself. This can be particularly problematic when the image data resides in memory. In this case, you can actually tag the DataRef with information that can help the system decide which importer to use. For more information, read Technical Note 1195 : Tagging Handle and Pointer Data References in QuickTime at the URL:

http://developer.apple.com/technotes/tn/tn1195.html


After you have selected an appropriate component, getting a CGImage out of that component is as easy as calling GraphicsImportCreateCGImage. This routine simply asks the QuickTime graphics importer to take whatever steps are necessary to load the image and create a CGImage from it.

All of these steps are summarized in code Listing 9.1. This routine is taken from the Chapter 9 sample code project called QuickTime Import. The application is very simple. It allows you to open any image that QuickTime has an importer for and displays that image in a window. The application contains some code for setting up the application and managing the open dialog. That code will not be repeated here. Listing 9.1 simply provides the code that imports image files into a CGImage.

Listing 9.1. Importing a CGImage Using QuickTime

void OpenImageFile(FSRef &whichFile) {     Handle fileDataRef = NULL;     OSType dataRefType = 0;     ComponentInstance graphicsImporter = NULL;     CGImageRef image = NULL;     // Create a DataRef from the file reference that was passed in.     QTNewDataReferenceFromFSRef(&whichFile, 0L,             &fileDataRef, &dataRefType);     if(fileDataRef) {             // Find an appropriate graphics importer for the             // given data ref.            GetGraphicsImporterForDataRef(fileDataRef,                    dataRefType, &graphicsImporter);     }     // If the system found an image importer for us to use then     // try to extract an image from it.     if(graphicsImporter) {            GraphicsImportCreateCGImage(graphicsImporter, &image, 0);            // we're done with the component so close it out            CloseComponent(graphicsImporter);            // We're done with the DataRef too            DisposeHandle(fileDataRef);     }     // if we got an image, then create a new window and put     // the image into it.     if(image) {             CreateImageWindow(image);             CGImageRelease(image);             image = NULL;     } } 

The sample project prompts the user to select an image file and then opens a window that displays the image found in the file. After selecting the file, the computer translates the user's selection into an FSRef, which is passed to the OpenImageFile routine.

Listing 9.1 uses the routine QTNewDataReferenceFromFSRef to create a DataRef from the FSSpec that is passed to the routine. It gets back both the DataRef and the OSType that describes the data it contains. If that routine returns successfully, the computer then tries to create a graphics import component by examining the data from the file using the routine GetGraphicsImporterForDataRef.

If the computer finds a graphics importer, it then calls the routine GraphicsImportCreateCGImage. After creating the image, the code closes the importer and disposes of the DataRef. The code takes the resulting image and passes it to a routine, CreateImageWindow, that opens a new window to display the image.

Export Image Example

Exporting an image from QuickTime is just as easy as importing one. The basic technique is to create a graphic exporter for the type of file you would like to export your image into. You provide the graphic exporter with a DataRef that describes where you would like the computer to put the compressed data. You also provide the CGImage that you would like to export. Once everything is set up, exporting the data is as easy as calling GraphicsExportDoExport.

If you follow the steps listed, you will get a graphics export with the default settings of the graphics exporter. If you want to customize the export settings, QuickTime provides a number of routines that begin with GraphicsExportSetSettings to assist you. The easiest way to set up the settings, however, is to use the routine GraphicsExportRequestSettings to put up a dialog that will modify the settings of the exporter.

The technique of exporting a CGImage into a PNG file is demonstrated by the QuickTime Export sample code. The routine that exports the image through QuickTime is show in listing 9.2:

Listing 9.2. Exporting an Image via QuickTime

void ExportPNGImage(CGImageRef image) {     Handle      dataRef;     OSType      dataRefType;     GraphicsExportComponent       exporter;     unsigned long                 exportSize;     // Open a graphics exporter for PNG files and point it at our image.     OpenADefaultComponent(GraphicsExporterComponentType,            kQTFileTypePNG, &exporter);     GraphicsExportSetInputCGImage(exporter, image);     // Then request the exporter's settings from the user     GraphicsExportRequestSettings(exporter, NULL, NULL);     // We're all set up to save. Ask the user where we     // should save the file     CFURLRef saveLocation = CopySaveLocation();     if(NULL != saveLocation) {             // Create a data ref to our destination.             QTNewDataReferenceFromCFURL(saveLocation, 0,                     &dataRef, &dataRefType);             CFRelease(saveLocation);             saveLocation = NULL;             // Set the destination in the exporter and export the image             GraphicsExportSetOutputDataReference(exporter,                     dataRef, dataRefType);             GraphicsExportDoExport(exporter, &exportSize);             DisposeHandle(dataRef);             dataRef = NULL;     }     CloseComponent(exporter);     exporter = NULL; } 

This code sample should look familiar at this point. The code begins by opening a QuickTime component. In this case, you are explicitly asking for a graphics exporter component capable of writing PNG files. After you have the component, you tell the exporter that we will be exporting the CGImage.

Next, call GraphicsExportSetInputCGImage to ask QuickTime to put up a settings dialog for the PNG exporter so the user can change the exporter's settings.

The routine CopySaveLocation puts up a save file dialog and returns the URL of the location the user has chosen for saving the document. You use this URL to create a destination DataRef for QuickTime. After telling the export component where it should save the image, you call GraphicsExportDoExport to save the new file. After that the code simply cleans up and returns.




Quartz 2D Graphics for Mac OS X Developers
Quartz 2D Graphics for Mac OS X Developers
ISBN: 0321336631
EAN: 2147483647
Year: 2006
Pages: 100

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