Exporting Images
Dispatch 14
Question: How can I use QuickTime to export a picture as an image file?
Graphics importer components provide a simple, flexible and
extensible way for you to draw pictures that are stored in a wide
variety of image file formats. They also turn out to be the easiest way
to export pictures to several file formats.
Normally you create a graphics importer instance with the
GetGraphicsImporterForFile call, or one of its relatives.
Afterwards you can call GraphicsImportExportImageFile to export
that image to a new file:
GetGraphicsImporterForFile(
&theExistingFile,
&gi);
GraphicsImportExportImageFile(
gi,
kQTFileTypeJPEG, // or one of several other file types
0, // ie, the default creator for this type
&theNewFile,
theScriptCode);
The file type determines the data format for the exported file.
For example, if you pass kQTFileTypeJPEG, a JPEG file will be created.
If the picture you want to export isn't already in a file,
it doesn't make sense to call GetGraphicsImporterForFile.
Instead, you can create an instance of the "picture file" graphics
importer yourself and give it a handle that contains a "source picture
file".
OpenADefaultComponent(
GraphicsImporterComponentType,
kQTFileTypePicture,
&gi);
GraphicsImportSetDataHandle(
gi,
thePictureFileHandle);
GraphicsImportExportImageFile(
gi,
kQTFileTypeJPEG,
0,
&theNewFile,
theScriptCode);
Picture files are just like picture handles, except that they have an
extra 512-byte header at the front. (Any data in this header is usually
ignored, but it must be there for historical reasons.) The graphics
importer for picture files expects and skips this 512-byte header, so you
must insert it.
PicHandle thePicture = /* create a picture */;
Handle thePictureFileHandle;
thePictureFileHandle = NewHandleClear(512);
HandAndHand((Handle)thePicture,thePictureFileHandle);
Finally, here's a function that puts it all together. This function
exports a picture to a file.
The new file is described by its type, creator, specification and script
code. If you don't know what script code to use, it's usually safe to use
smSystemScript.
#include <OSUtils.h>
#include <ImageCompression.h>
#include <QuickTimeComponents.h>
OSErr ExportPicHandleToFile(
PicHandle thePicture,
OSType filetype,
OSType filecreator,
FSSpec *filespec,
ScriptCode filescriptcode)
{
Handle h;
OSErr err;
GraphicsImportComponent gi = 0;
// Convert the picture handle into a PICT file (still in a handle)
// by adding a 512-byte header to the start.
h = NewHandleClear(512);
err = MemError();
if(err) goto bail;
err = HandAndHand((Handle)thePicture,h);
err = OpenADefaultComponent(
GraphicsImporterComponentType,
kQTFileTypePicture,
&gi);
if(err) goto bail;
err = GraphicsImportSetDataHandle(gi, h);
if(err) goto bail;
err = GraphicsImportExportImageFile(
gi,
filetype,
filecreator,
filespec,
filescriptcode);
if(err) goto bail;
bail:
if(gi) CloseComponent(gi);
if(h) DisposeHandle(h);
return err;
}
Extra credit
One problem with using HandToHand to add the 512-byte header to the
picture handle is that you make an extra copy of the picture data.
If you don't need the original picture handle after the export, you could
fix this by using Munger to insert the header into the handle:
PicHandle thePicture = /* create a picture */;
Handle thePictureFileHandle = (Handle)thePicture;
char randomData[512];
Munger(thePictureFileHandle, 0, nil, 0, randomData, 512);
(Munger is documented in Inside Macintosh: Operating System Utilities.
It rhymes with "plunger.")
Could you write my user interface for me? Please?
If you've been gazing hungrily at the "Export..." command in PictureViewer
Pro and wishing you could implement a matching user experience, you're in luck.
This command is actually implemented by a single call,
GraphicsImportDoExportImageFileDialog. All of the parameters after
the component are optional, so you can call it as simply as this:
err = GraphicsImportDoExportImageFileDialog(
gi, nil, nil, nil, nil, nil, nil);
What were those export formats again?
Under QuickTime 3.0, the available still image export formats are BMP, JPEG,
Photoshop, Picture and QuickTime Image. However, future versions may bring more
formats and extensibility.
Your application can find out more information about available export formats
by calling the GraphicsImportGetExportImageTypeList
function. This function returns an atom container (which your application must
dispose of) containing several kGraphicsExportGroup atoms. Each of these
represents one export format, and has child atoms which indicate the file type
(kGraphicsExportFileType), human-readable format name (kGraphicsExportDescription), file
extension (kGraphicsExportExtension) and optionally MIME type (kGraphicsExportMIMEType).
Here's a code fragment showing how you could find out the available export
file types. Error-handling code has been removed.
QTAtomContainer theExportInfo = nil;
short theNumberOfExportTypes, i;
GraphicsImportGetExportImageTypeList(
gi,
&theExportInfo);
theNumberOfExportTypes = QTCountChildrenOfType(
theExportInfo,
kParentAtomIsContainer,
kGraphicsExportGroup); // 'expo'
for(i = 1; i <= theNumberOfExportTypes; i++) {
QTAtom groupAtom, fileTypeAtom;
OSType fileType;
groupAtom = QTFindChildByIndex(
theExportInfo,
kParentAtomIsContainer,
kGraphicsExportGroup,
i,
nil);
fileTypeAtom = QTFindChildByIndex(
theExportInfo,
groupAtom,
kGraphicsExportFileType, // 'ftyp'
1,
nil);
QTCopyAtomDataToPtr(
theExportInfo,
fileTypeAtom,
false,
sizeof(fileType),
&fileType,
nil);
fileType = EndianU32_BtoN(fileType); // data in QT atoms is always big-endian
}
QTDisposeAtomContainer(theExportInfo);
See Also
QuickTime 3 Reference - Graphics Importers
Change History
28 Apr 98 - jsam - First published
15 May 98 - jsam - Revised
|