<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://commons.oreilly.com/wiki/skins/common/feed.css?97"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>QuickTime for Java: A Developer's Notebook/Working with QuickDraw - Revision history</title>
		<link>http://commons.oreilly.com/wiki/index.php?title=QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw&amp;action=history</link>
		<description>Revision history for this page on the wiki</description>
		<language>en</language>
		<generator>MediaWiki 1.11.0</generator>
		<lastBuildDate>Mon, 20 May 2013 16:53:30 GMT</lastBuildDate>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw&amp;diff=7240&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 13:22, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Fri, 07 Mar 2008 13:22:47 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw&amp;diff=7161&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 13:17, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Fri, 07 Mar 2008 13:17:34 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw</comments>		</item>
		<item>
			<title>Evanlenz: 1 revision(s)</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw&amp;diff=4463&amp;oldid=prev</link>
			<description>&lt;p&gt;1 revision(s)&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 00:25, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Fri, 07 Mar 2008 00:25:58 GMT</pubDate>			<dc:creator>Evanlenz</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw&amp;diff=4462&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 00:17, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 124:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 124:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-1. Writing and reading PICT files'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-1. Writing and reading PICT files'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developer's &lt;/del&gt;Notebook_I_5_tt67.png|Writing and reading PICT files]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developers &lt;/ins&gt;Notebook_I_5_tt67.png|Writing and reading PICT files]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 327:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 327:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-2. Converting movie to Java AWT Image'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-2. Converting movie to Java AWT Image'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developer's &lt;/del&gt;Notebook_I_5_tt69.png|Converting movie to Java AWT Image]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developers &lt;/ins&gt;Notebook_I_5_tt69.png|Converting movie to Java AWT Image]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 422:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 422:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-3. Converting movie to Java AWT image (a better way)'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-3. Converting movie to Java AWT image (a better way)'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developer's &lt;/del&gt;Notebook_I_5_tt70.png|Converting movie to Java AWT image (a better way)]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developers &lt;/ins&gt;Notebook_I_5_tt70.png|Converting movie to Java AWT image (a better way)]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 569:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 569:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-4. Graphics primitives drawn with QDGraphics'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-4. Graphics primitives drawn with QDGraphics'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developer's &lt;/del&gt;Notebook_I_5_tt73.png|Graphics primitives drawn with QDGraphics]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developers &lt;/ins&gt;Notebook_I_5_tt73.png|Graphics primitives drawn with QDGraphics]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 662:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 662:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-5. Screen capture'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-5. Screen capture'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developer's &lt;/del&gt;Notebook_I_5_tt74.png|Screen capture]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developers &lt;/ins&gt;Notebook_I_5_tt74.png|Screen capture]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 702:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 702:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-6. Converting between QuickDraw objects'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-6. Converting between QuickDraw objects'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developer's &lt;/del&gt;Notebook_I_5_tt75.png|Converting between QuickDraw objects]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developers &lt;/ins&gt;Notebook_I_5_tt75.png|Converting between QuickDraw objects]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 846:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 846:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-7. Drawing with a Matrix'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-7. Drawing with a Matrix'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developer's &lt;/del&gt;Notebook_I_5_tt76.png|Drawing with a Matrix]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developers &lt;/ins&gt;Notebook_I_5_tt76.png|Drawing with a Matrix]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 915:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 915:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-8. Drawing with blend graphics mode'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-8. Drawing with blend graphics mode'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developer's &lt;/del&gt;Notebook_I_5_tt78.png|Drawing with blend graphics mode]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developers &lt;/ins&gt;Notebook_I_5_tt78.png|Drawing with blend graphics mode]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 927:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 927:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-9. Drawing with transparent graphics mode'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 5-9. Drawing with transparent graphics mode'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developer's &lt;/del&gt;Notebook_I_5_tt79.png|Drawing with transparent graphics mode]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:QuickTime for Java: A &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Developers &lt;/ins&gt;Notebook_I_5_tt79.png|Drawing with transparent graphics mode]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key wikicontent:diff:version:1.11a:oldid:4311:newid:4462 --&gt;
&lt;/table&gt;</description>
			<pubDate>Fri, 07 Mar 2008 00:17:35 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw</comments>		</item>
		<item>
			<title>Evanlenz: 1 revision(s)</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw&amp;diff=4311&amp;oldid=prev</link>
			<description>&lt;p&gt;1 revision(s)&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 00:16, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Fri, 07 Mar 2008 00:16:20 GMT</pubDate>			<dc:creator>Evanlenz</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw&amp;diff=4310&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 00:15, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Fri, 07 Mar 2008 00:15:32 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw</comments>		</item>
		<item>
			<title>Evanlenz: 1 revision(s)</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw&amp;diff=4159&amp;oldid=prev</link>
			<description>&lt;p&gt;1 revision(s)&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 23:57, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Thu, 06 Mar 2008 23:57:57 GMT</pubDate>			<dc:creator>Evanlenz</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw&amp;diff=4158&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{QuickTime for Java: A Developer's Notebook/TOC}}&lt;br /&gt;
And now, on to the oldest, cruftiest, yet can't-live-without-it-iest part of QTJ: QuickDraw. QuickDraw is a graphics API that can be traced all the way back to that first Mac Steve Jobs pulled out of a bag and showed the press more than 20 years ago. You know—back when Mac supported all of two colors: black and white.&lt;br /&gt;
&lt;br /&gt;
Don't worry; it's gotten a lot better since then.&lt;br /&gt;
&lt;br /&gt;
To be fair, a native Mac OS X application being written today from scratch probably would use the shiny new &amp;quot;Quartz 2D&amp;quot; API. And as a Java developer, the included Java 2D API is at least as capable as QuickDraw, with extension packages like Java Advanced Imaging (JAI) only making things better.&lt;br /&gt;
&lt;br /&gt;
The real advantage to understanding QuickDraw is that it's what's used to work with captured images (see [[QuickTime for Java: A Developer's Notebook/Capture|Chapter 6]]) and individual video samples (see [[QuickTime for Java: A Developer's Notebook/Video Media|Chapter 8]]). It is also a reasonably capable graphics API in its own right, supporting import from and export to many formats (most of which J2SE lacked until 1.4), affine transformations, compositing, and more.&lt;br /&gt;
&lt;br /&gt;
== Getting and Saving Picts ==&lt;br /&gt;
&lt;br /&gt;
If you had a Mac before Mac OS X, you probably are very familiar with ''picts'' , because they were the native graphics file format on the old Mac OS. Taking screenshots would create pict files, as would saving your work in graphics applications. Developers used pict resources in their applications to provide graphics, splash screens, etc.&lt;br /&gt;
&lt;br /&gt;
Actually, a number of tightly coupled concepts relate to picts. The native structure for working with a series of drawing commands is called a &amp;lt;tt&amp;gt;Picture actually&amp;lt;/tt&amp;gt;. This struct, along with the functions that use it, are wrapped by the QTJ class &amp;lt;tt&amp;gt;quicktime.qd.Pict&amp;lt;/tt&amp;gt;. There's also a file format for storing picts, which can contain either drawing commands or bit-mapped images—files in this format usually have a ''.pct'' or ''.pict'' extension. QTJ's &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt; class has methods to read and write these files, and because it's easy to create &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt;s from &amp;lt;tt&amp;gt;Movie&amp;lt;/tt&amp;gt;s, &amp;lt;tt&amp;gt;Track&amp;lt;/tt&amp;gt;s, &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt;s, &amp;lt;tt&amp;gt;SequenceGrabber&amp;lt;/tt&amp;gt;s (capture devices), etc., it's a very useful class.&lt;br /&gt;
&lt;br /&gt;
=== How do I do that? ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;PictTour.java&amp;lt;/tt&amp;gt; application, shown in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-EX-1|Example 5-1]], exercises the basics of getting, saving, and loading &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt;s.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''Compile and run this example with ant run-ch05-picttour from the downloadable book code''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-EX-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 5-1. Opening and saving Picts'''&lt;br /&gt;
&lt;br /&gt;
 package com.oreilly.qtjnotebook.ch05;&lt;br /&gt;
 &lt;br /&gt;
 import quicktime.*;&lt;br /&gt;
 import quicktime.app.view.*;&lt;br /&gt;
 import quicktime.std.*;&lt;br /&gt;
 import quicktime.std.image.*;&lt;br /&gt;
 import quicktime.io.*;&lt;br /&gt;
 import quicktime.qd.*;&lt;br /&gt;
 &lt;br /&gt;
 import java.awt.*;&lt;br /&gt;
 import java.io.*;&lt;br /&gt;
 import com.oreilly.qtjnotebook.ch01.QTSessionCheck;&lt;br /&gt;
 &lt;br /&gt;
 public class PictTour extends Object {&lt;br /&gt;
 &lt;br /&gt;
  static final int[  ] imagetypes =&lt;br /&gt;
     { StdQTConstants.kQTFileTypeQuickTimeImage};&lt;br /&gt;
 &lt;br /&gt;
  static int frameX = -1;&lt;br /&gt;
  static int frameY = -1;&lt;br /&gt;
 &lt;br /&gt;
  public static void main (String[  ] args) {&lt;br /&gt;
    try {&lt;br /&gt;
        QTSessionCheck.check( );&lt;br /&gt;
 &lt;br /&gt;
        // import a graphic&lt;br /&gt;
        QTSessionCheck.check( );&lt;br /&gt;
        QTFile inFile =  QTFile.standardGetFilePreview (imagetypes);&lt;br /&gt;
        GraphicsImporter importer =&lt;br /&gt;
            new GraphicsImporter (inFile);&lt;br /&gt;
        showFrameForImporter (importer,&lt;br /&gt;
                              &amp;quot;Original Import&amp;quot;);&lt;br /&gt;
        // get a pict object and then save it&lt;br /&gt;
        // then load again and show&lt;br /&gt;
        Pict pict = importer.getAsPicture( );&lt;br /&gt;
        String absPictPath = (new File (&amp;quot;pict.pict&amp;quot;)).getAbsolutePath( );&lt;br /&gt;
        File pictFile = new File (absPictPath);&lt;br /&gt;
        if (pictFile.exists( ))&lt;br /&gt;
            pictFile.delete( );&lt;br /&gt;
        try { Thread.sleep (1000); } catch (InterruptedException ie) {  }&lt;br /&gt;
        pict.writeToFile (pictFile);&lt;br /&gt;
        QTFile pictQTFile = new QTFile (pictFile);&lt;br /&gt;
        GraphicsImporter pictImporter =&lt;br /&gt;
            new GraphicsImporter (pictQTFile);&lt;br /&gt;
        showFrameForImporter (pictImporter,&lt;br /&gt;
                              &amp;quot;pict.pict&amp;quot;);&lt;br /&gt;
        // write to a pict file from importer&lt;br /&gt;
        // then load and show it&lt;br /&gt;
        String absGIPictPath = (new File (&amp;quot;gipict.pict&amp;quot;)).getAbsolutePath( );&lt;br /&gt;
        QTFile giPictQTFile = new QTFile (absGIPictPath);&lt;br /&gt;
        if (giPictQTFile.exists( ))&lt;br /&gt;
            giPictQTFile.delete( );&lt;br /&gt;
        try { Thread.sleep (1000); } catch (InterruptedException ie) {  }&lt;br /&gt;
        importer.saveAsPicture (giPictQTFile,&lt;br /&gt;
                                IOConstants.smSystemScript);&lt;br /&gt;
        GraphicsImporter giPictImporter =&lt;br /&gt;
            new GraphicsImporter (giPictQTFile);&lt;br /&gt;
        showFrameForImporter (giPictImporter,&lt;br /&gt;
                              &amp;quot;gipict.pict&amp;quot;);&lt;br /&gt;
    } catch (Exception e) {&lt;br /&gt;
        e.printStackTrace( );&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  public static void showFrameForImporter (GraphicsImporter gi,&lt;br /&gt;
                                         String frameTitle) &lt;br /&gt;
    throws QTException {&lt;br /&gt;
    QTComponent qtc = QTFactory.makeQTComponent (gi);&lt;br /&gt;
    Component c = qtc.asComponent( );&lt;br /&gt;
    Frame f = new Frame (frameTitle);&lt;br /&gt;
    f.add (c);&lt;br /&gt;
    f.pack( );&lt;br /&gt;
    if (frameX =  = -1) {&lt;br /&gt;
        frameX = f.getLocation( ).x;&lt;br /&gt;
        frameY = f.getLocation( ).y;&lt;br /&gt;
    } else {&lt;br /&gt;
        Point location = new Point (frameX += 20,&lt;br /&gt;
                                    frameY += 20);&lt;br /&gt;
        f.setLocation (location);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    f.setVisible (true);&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Warning'''&lt;br /&gt;
&lt;br /&gt;
The two &amp;lt;tt&amp;gt;Thread.sleep( )&amp;lt;/tt&amp;gt; calls are here only as a workaround to a problem I saw while developing this example—reading a file I'd just written proved crashy (maybe the file wasn't fully closed?). Because it's unlikely you'll write a file and immediately reread it, this isn't something you'll want or need to do in your code.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When run, this example prompts the user for a graphics file, which then is displayed in three windows, as shown in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-FIG-1|Figure 5-1]]. These represent three different means of loading the pict.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-FIG-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-1. Writing and reading PICT files'''&lt;br /&gt;
&lt;br /&gt;
[[Image:QuickTime for Java: A Developer's Notebook_I_5_tt67.png|Writing and reading PICT files]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What just happened? ===&lt;br /&gt;
&lt;br /&gt;
You can get picts in a number of ways in QTJ. The first example here is to use a &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt; to load an image file in some arbitrary format, and then call &amp;lt;tt&amp;gt;getAsPicture( )&amp;lt;/tt&amp;gt; to get a &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt; object. This is the easiest way to get a &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt; from an arbitrary file—if you knew for sure that a given file was in the pict file format, you could use &amp;lt;tt&amp;gt;Pict.fromFile( )&amp;lt;/tt&amp;gt; instead, but that does not check to ensure the file really is a pict. So, the safe thing to do is to use a &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt;, let it figure out the format of the source file, and then convert to pict if necessary with &amp;lt;tt&amp;gt;getAsPicture( )&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Writing a pict file to disk is easy: just call &amp;lt;tt&amp;gt;writeToFile()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
Curiously, this takes a &amp;lt;tt&amp;gt;java.io.File&amp;lt;/tt&amp;gt;, not a &amp;lt;tt&amp;gt;QTFile&amp;lt;/tt&amp;gt;, like so many other I/O routines in QTJ.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You also can write a &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt; to disk by using the &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt;'s &amp;lt;tt&amp;gt;saveAsPicture( )&amp;lt;/tt&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''Yes, it is kind of weird to use the &amp;quot;importer&amp;quot; for what is effectively an &amp;quot;export.''&amp;quot;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The example uses both of these methods to write pict files to disk—&amp;lt;tt&amp;gt;Pict.writeToFile( )&amp;lt;/tt&amp;gt; creates ''pict.pict'' and &amp;lt;tt&amp;gt;GraphicsImporter.saveAsPicture( )&amp;lt;/tt&amp;gt; creates ''gipict.pict''. Each file is then reloaded with &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt;s. Conveniently, a &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt; can be used with a &amp;lt;tt&amp;gt;QTFactory&amp;lt;/tt&amp;gt; to create a &amp;lt;tt&amp;gt;QTComponent&amp;lt;/tt&amp;gt; (see [[QuickTime for Java: A Developer's Notebook/Working with Components#Importing and Exporting Graphics|Section 4.4]] in [[QuickTime for Java: A Developer's Notebook/Working with Components|Chapter 4]]), which is how the imported picts are shown on-screen.&lt;br /&gt;
&lt;br /&gt;
=== What about . . . ===&lt;br /&gt;
&lt;br /&gt;
. . . other ways to get pictures? Look at the &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt; class and you'll see several static &amp;lt;tt&amp;gt;fromXXX( )&amp;lt;/tt&amp;gt; methods that provide &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt;s from &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt;s, &amp;lt;tt&amp;gt;GraphicsExporter&amp;lt;/tt&amp;gt;s, &amp;lt;tt&amp;gt;Movie&amp;lt;/tt&amp;gt;s, &amp;lt;tt&amp;gt;Track&amp;lt;/tt&amp;gt;s, and other QTJ classes.&lt;br /&gt;
&lt;br /&gt;
Also, why does this example go through the hassle of creating absolute path strings and passing those to the &amp;lt;tt&amp;gt;QTFile&amp;lt;/tt&amp;gt; constructor? It's a workaround to an apparent bug in QTJ for Windows: when you use a relative path (like &amp;lt;tt&amp;gt;Pict.writeToFile (new File(&amp;quot;MyPict.pict&amp;quot;))&amp;lt;/tt&amp;gt;), QTJ sometimes writes the file not to the current directory, but rather to the last directory it accessed. In this case, that means the directory it read the source image from. Specifying absolute paths works around this problem.&lt;br /&gt;
&lt;br /&gt;
== Getting a Pict from a Movie ==&lt;br /&gt;
&lt;br /&gt;
If you're working with movies, you'll probably want to be able to get a pict from some arbitrary time in the movie. You could use this for identifying movies via thumbnail icons, identifying segments on a timeline GUI, etc. This action is so common, and it's really easy.&lt;br /&gt;
&lt;br /&gt;
=== How do I do that? ===&lt;br /&gt;
&lt;br /&gt;
To grab a movie at a certain time, you just need a one-line call to &amp;lt;tt&amp;gt;Movie.getPict( )&amp;lt;/tt&amp;gt; , as exercised by the &amp;lt;tt&amp;gt;dumpToPict( )&amp;lt;/tt&amp;gt; method shown here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''Notice I don't say &amp;quot;grab the current movie frame&amp;quot; because the movie could have other on-screen elements like text, sprites, other movies, etc., not just one frame of one video track''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 public void dumpToPict ( ) {&lt;br /&gt;
   try {&lt;br /&gt;
       float oldRate = movie.getRate( );&lt;br /&gt;
       movie.stop( );&lt;br /&gt;
       Pict pict = movie.getPict(movie.getTime( ));&lt;br /&gt;
       String absPictPath =&lt;br /&gt;
           (new File (&amp;quot;movie.pict&amp;quot;)).getAbsolutePath( );&lt;br /&gt;
       pict.writeToFile (new File (absPictPath));&lt;br /&gt;
       movie.setRate (oldRate);&lt;br /&gt;
   } catch (Exception e) {&lt;br /&gt;
       e.printStackTrace( );&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This method stops the movie if it's playing and stores the previous play rate. Then it creates a &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt; on the movie's current time and saves it to a file called ''movie.pict''. Then it restarts the movie.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''The downloadable book code exercises this in a demo called PictFromMovie. Run it with ant run-ch05-pictfrommovie''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What about . . . ===&lt;br /&gt;
&lt;br /&gt;
. . . not stopping the movie? I haven't had good results with this call unless the movie is stopped. At best, it makes the playback choppy for a few seconds; at worst, it crashes.&lt;br /&gt;
&lt;br /&gt;
== Converting a Movie Image to a Java Image ==&lt;br /&gt;
&lt;br /&gt;
It's possible you'll want to grab the current display of the movie and get it into a &amp;lt;tt&amp;gt;java.awt.Image&amp;lt;/tt&amp;gt;. A convenient method call has been provided for just this task; unfortunately, it doesn't work very well, so a &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt;-based workaround is needed.&lt;br /&gt;
&lt;br /&gt;
=== How do I do that? ===&lt;br /&gt;
&lt;br /&gt;
QTJ provides &amp;lt;tt&amp;gt;QTImageProducer&amp;lt;/tt&amp;gt; , an implementation of the AWT &amp;lt;tt&amp;gt;ImageProducer&amp;lt;/tt&amp;gt; interface. &amp;lt;tt&amp;gt;ImageProducer&amp;lt;/tt&amp;gt; dates back to Java 1.0, and was designed to handle latency and unreliability when loading images over the network—issues that are irrelevant in typical desktop cases.&lt;br /&gt;
&lt;br /&gt;
The most straightforward way to get an image from a movie is to get a &amp;lt;tt&amp;gt;QTImageProducer&amp;lt;/tt&amp;gt; from a &amp;lt;tt&amp;gt;MoviePlayer&amp;lt;/tt&amp;gt;, the object typically used to create a lightweight, Swing-ready &amp;lt;tt&amp;gt;QTJComponent&amp;lt;/tt&amp;gt;. The &amp;lt;tt&amp;gt;ConvertToImageBad&amp;lt;/tt&amp;gt; application in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-EX-2|Example 5-2]] demonstrates this approach.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''Makes sense, doesn't it? The MoviePlayer needs to generate AWT images for the lightweight QTJComponent, so that's what you get an ImageProducer from''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-EX-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 5-2. Using MoviePlayer's QTImageProducer'''&lt;br /&gt;
&lt;br /&gt;
 package com.oreilly.qtjnotebook.ch05;&lt;br /&gt;
  &lt;br /&gt;
 import com.oreilly.qtjnotebook.ch01.QTSessionCheck;&lt;br /&gt;
  &lt;br /&gt;
 import java.awt.*;&lt;br /&gt;
 import java.awt.event.*;&lt;br /&gt;
 import javax.swing.*;&lt;br /&gt;
 import quicktime.*;&lt;br /&gt;
 import quicktime.app.view.*;&lt;br /&gt;
 import quicktime.io.*;&lt;br /&gt;
 import quicktime.qd.*;&lt;br /&gt;
 import quicktime.std.*;&lt;br /&gt;
 import quicktime.std.clocks.*;&lt;br /&gt;
 import quicktime.std.movies.*;&lt;br /&gt;
  &lt;br /&gt;
 public class ConvertToJavaImageBad extends Frame&lt;br /&gt;
   implements ActionListener {&lt;br /&gt;
  &lt;br /&gt;
   Movie movie;&lt;br /&gt;
   MoviePlayer player;&lt;br /&gt;
   MovieController controller;&lt;br /&gt;
   QTComponent qtc;&lt;br /&gt;
   static int nextFrameX, nextFrameY;&lt;br /&gt;
   QTImageProducer ip;&lt;br /&gt;
  &lt;br /&gt;
   public static void main (String[  ] args) {&lt;br /&gt;
       ConvertToJavaImageBad ctji = new ConvertToJavaImageBad( );&lt;br /&gt;
       ctji.pack( );&lt;br /&gt;
       ctji.setVisible(true);&lt;br /&gt;
       Rectangle ctjiBounds = ctji.getBounds( );&lt;br /&gt;
       nextFrameX = ctjiBounds.x + ctjiBounds.width;&lt;br /&gt;
       nextFrameY = ctjiBounds.y + ctjiBounds.height;&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   public ConvertToJavaImageBad( ) {&lt;br /&gt;
       super (&amp;quot;QuickTime Movie&amp;quot;);&lt;br /&gt;
       try {&lt;br /&gt;
           // get movie&lt;br /&gt;
           QTSessionCheck.check( );&lt;br /&gt;
           QTFile file =&lt;br /&gt;
               QTFile.standardGetFilePreview (QTFile.kStandardQTFileTypes);&lt;br /&gt;
           OpenMovieFile omFile = OpenMovieFile.asRead(file);&lt;br /&gt;
           movie = Movie.fromFile(omFile);&lt;br /&gt;
           player = new MoviePlayer (movie);&lt;br /&gt;
           controller = new MovieController (movie);&lt;br /&gt;
           // build gui&lt;br /&gt;
           qtc = QTFactory.makeQTComponent (controller);&lt;br /&gt;
           Component c = qtc.asComponent( );&lt;br /&gt;
           setLayout (new BorderLayout( ));&lt;br /&gt;
           add (c, BorderLayout.CENTER);&lt;br /&gt;
           Button imageButton = new Button (&amp;quot;Make Java Image&amp;quot;);&lt;br /&gt;
           add (imageButton, BorderLayout.SOUTH);&lt;br /&gt;
           imageButton.addActionListener (this);&lt;br /&gt;
           movie.start( );&lt;br /&gt;
           // set up close-to-quit&lt;br /&gt;
           addWindowListener (new WindowAdapter( ) {&lt;br /&gt;
                   public void windowClosing (WindowEvent we) {&lt;br /&gt;
                       System.exit(0);&lt;br /&gt;
                   }&lt;br /&gt;
               });&lt;br /&gt;
       } catch (QTException qte) {&lt;br /&gt;
           qte.printStackTrace( );&lt;br /&gt;
       }&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
   public void actionPerformed (ActionEvent e) {&lt;br /&gt;
       grabMovieImage( );&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   public void grabMovieImage( ) {&lt;br /&gt;
       try {&lt;br /&gt;
           // lazy instantiation of ImageProducer&lt;br /&gt;
           if (ip =  = null) {&lt;br /&gt;
               QDRect bounds = movie.getBounds( );&lt;br /&gt;
               Dimension dimBounds =&lt;br /&gt;
                   new Dimension (bounds.getWidth( ), bounds.getHeight( ));&lt;br /&gt;
               ip = new QTImageProducer (player, dimBounds);&lt;br /&gt;
            }&lt;br /&gt;
  &lt;br /&gt;
           // stop movie to take picture&lt;br /&gt;
           boolean wasPlaying = false;&lt;br /&gt;
           if (movie.getRate( ) &amp;gt; 0) {&lt;br /&gt;
               movie.stop( );&lt;br /&gt;
               wasPlaying = true;&lt;br /&gt;
           }&lt;br /&gt;
  &lt;br /&gt;
           // convert from MoviePlayer to java.awt.Image&lt;br /&gt;
           Image image = Toolkit.getDefaultToolkit( ).createImage (ip);&lt;br /&gt;
           // make a swing icon out of it and show it in a frame&lt;br /&gt;
           ImageIcon icon = new ImageIcon (image);&lt;br /&gt;
           JLabel label = new JLabel (icon);&lt;br /&gt;
           JFrame frame = new JFrame (&amp;quot;Java image&amp;quot;);&lt;br /&gt;
           frame.getContentPane( ).add(label);&lt;br /&gt;
           frame.pack( );&lt;br /&gt;
           frame.setLocation (nextFrameX += 10,&lt;br /&gt;
                              nextFrameY += 10);&lt;br /&gt;
           frame.setVisible(true);&lt;br /&gt;
           // restart movie&lt;br /&gt;
           if (wasPlaying)&lt;br /&gt;
               movie.start( );&lt;br /&gt;
       } catch (QTException qte) {&lt;br /&gt;
           qte.printStackTrace( );&lt;br /&gt;
       }&lt;br /&gt;
   } &lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This application is shown in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-FIG-2|Figure 5-2]]. When you click the Make Java Image button, the movie is stopped, an AWT &amp;lt;tt&amp;gt;Image&amp;lt;/tt&amp;gt; of the current display is made, and that &amp;lt;tt&amp;gt;Image&amp;lt;/tt&amp;gt; is opened in another window.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-FIG-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-2. Converting movie to Java AWT Image'''&lt;br /&gt;
&lt;br /&gt;
[[Image:QuickTime for Java: A Developer's Notebook_I_5_tt69.png|Converting movie to Java AWT Image]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Warning'''&lt;br /&gt;
&lt;br /&gt;
This is a ''negative'' example. Keep reading for why you don't want to use this code, and for a superior alternative.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What just happened? ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;grabMovieImage()&amp;lt;/tt&amp;gt; method creates a &amp;lt;tt&amp;gt;QTImageProducer&amp;lt;/tt&amp;gt; from the &amp;lt;tt&amp;gt;MoviePlayer&amp;lt;/tt&amp;gt; and hands it to the AWT Toolkit method &amp;lt;tt&amp;gt;createImage()&amp;lt;/tt&amp;gt;. This call returns an AWT &amp;lt;tt&amp;gt;Image&amp;lt;/tt&amp;gt; that (because it's a nice, clean, one-line call) is stuffed into a Swing &amp;lt;tt&amp;gt;ImageIcon&amp;lt;/tt&amp;gt; and put on-screen.&lt;br /&gt;
&lt;br /&gt;
This is more of a &amp;quot;what the heck&amp;quot; than a &amp;quot;what just happened.&amp;quot; If your results are anything like mine, you're probably wondering why the movie stopped the first time you snapped a picture, even though the sound continued. Or why, for that matter, subsequent pictures seem to be later in the movie, meaning the decompression and decoding of the video is still working, but that it's just not getting to the screen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
Or not—maybe they'll have fixed it by the time you read this. At any rate, as of this writing, the &amp;lt;tt&amp;gt;QTImageProducer&amp;lt;/tt&amp;gt; provided by a &amp;lt;tt&amp;gt;MoviePlayer&amp;lt;/tt&amp;gt; is not to be trusted.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== A Better Movie-to-Java Image Converter ==&lt;br /&gt;
&lt;br /&gt;
The code shown in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#Converting a Movie Image to a Java Image|Section 5.3]] is error-prone and nasty. On the other hand, a &amp;lt;tt&amp;gt;QTImageProducer&amp;lt;/tt&amp;gt; is available from the &amp;lt;tt&amp;gt;GraphicsImporterDrawer&amp;lt;/tt&amp;gt;. It does not have to work with a moving target like the &amp;lt;tt&amp;gt;MoviePlayer&amp;lt;/tt&amp;gt; does. If only you could use that one instead . . . .&lt;br /&gt;
&lt;br /&gt;
=== How do I do that? ===&lt;br /&gt;
&lt;br /&gt;
The example program &amp;lt;tt&amp;gt;ConvertToJavaImageBetter&amp;lt;/tt&amp;gt; has a different implementation of the &amp;lt;tt&amp;gt;grabMovieImage( )&amp;lt;/tt&amp;gt; method, as shown in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-EX-3|Example 5-3]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''Run this example with ant run-ch05-convert-tojava-imagebetter''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-EX-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 5-3. In-memory pict import to use GraphicsImporterDrawer's QTImageProducer'''&lt;br /&gt;
&lt;br /&gt;
   public void grabMovieImage( ) {&lt;br /&gt;
       try {&lt;br /&gt;
           // stop movie to take picture&lt;br /&gt;
           boolean wasPlaying = false;&lt;br /&gt;
           if (movie.getRate( ) &amp;gt; 0) {&lt;br /&gt;
               movie.stop( );&lt;br /&gt;
               wasPlaying = true;&lt;br /&gt;
           }&lt;br /&gt;
  &lt;br /&gt;
           // take a pict&lt;br /&gt;
           Pict pict = movie.getPict (movie.getTime( ));&lt;br /&gt;
           &lt;br /&gt;
           // add 512-byte header that pict would have as file&lt;br /&gt;
           byte[  ] newPictBytes =&lt;br /&gt;
               new byte [pict.getSize( ) + 512];&lt;br /&gt;
           pict.copyToArray (0,&lt;br /&gt;
                             newPictBytes,&lt;br /&gt;
                             512,&lt;br /&gt;
                             newPictBytes.length - 512);&lt;br /&gt;
           pict = new Pict (newPictBytes);&lt;br /&gt;
           &lt;br /&gt;
           // export it&lt;br /&gt;
           DataRef ref = new DataRef (pict,&lt;br /&gt;
                                     StdQTConstants.kDataRefQTFileTypeTag,&lt;br /&gt;
                                     &amp;quot;PICT&amp;quot;);&lt;br /&gt;
           gi.setDataReference (ref);&lt;br /&gt;
           QDRect rect = gi.getSourceRect ( );&lt;br /&gt;
           Dimension dim = new Dimension (rect.getWidth( ),&lt;br /&gt;
                                          rect.getHeight( ));&lt;br /&gt;
           QTImageProducer ip = new QTImageProducer (gid, dim);&lt;br /&gt;
  &lt;br /&gt;
           // convert from MoviePlayer to java.awt.Image&lt;br /&gt;
           Image image = Toolkit.getDefaultToolkit( ).createImage (ip);&lt;br /&gt;
           // make a swing icon out of it and show it in a frame&lt;br /&gt;
           ImageIcon icon = new ImageIcon (image);&lt;br /&gt;
           JLabel label = new JLabel (icon);&lt;br /&gt;
           JFrame frame = new JFrame (&amp;quot;Java image&amp;quot;);&lt;br /&gt;
           frame.getContentPane( ).add(label);&lt;br /&gt;
           frame.pack( );&lt;br /&gt;
           frame.setLocation (nextFrameX += 10,&lt;br /&gt;
                              nextFrameY += 10);&lt;br /&gt;
           frame.setVisible(true);&lt;br /&gt;
           &lt;br /&gt;
           // restart movie&lt;br /&gt;
           if (wasPlaying)&lt;br /&gt;
               movie.start( );&lt;br /&gt;
       } catch (QTException qte) {&lt;br /&gt;
           qte.printStackTrace( );&lt;br /&gt;
       }&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Try out this example and you should be able to create multiple AWT &amp;lt;tt&amp;gt;Image&amp;lt;/tt&amp;gt;s without harming playback of the movie, as exhibited in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-FIG-3|Figure 5-3]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-FIG-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-3. Converting movie to Java AWT image (a better way)'''&lt;br /&gt;
&lt;br /&gt;
[[Image:QuickTime for Java: A Developer's Notebook_I_5_tt70.png|Converting movie to Java AWT image (a better way)]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What just happened? ===&lt;br /&gt;
&lt;br /&gt;
This isn't a hack. It's close, though.&lt;br /&gt;
&lt;br /&gt;
Once the movie is paused, the key is to get the movie's display into a &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt;. Once that's done, it's easy to get a &amp;lt;tt&amp;gt;QTImageProducer&amp;lt;/tt&amp;gt; from a &amp;lt;tt&amp;gt;GraphicsImporterDrawer&amp;lt;/tt&amp;gt; and an image from the AWT Toolkit.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''Note to self: pitch ''QuickTime for Java Hacks'' to O'Reilly!''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The problem is getting the image into a &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt;. If you look at the Javadoc, you might see one way to connect the dots: get a &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt; from the &amp;lt;tt&amp;gt;Movie&amp;lt;/tt&amp;gt;, save that to disk, then turn around and import. It would look something like this:&lt;br /&gt;
&lt;br /&gt;
 Pict pict = movie.getPict (movie.getTime( ));&lt;br /&gt;
 QTFile tempFile = new QTFile (new java.io.File (&amp;quot;temppict.pict&amp;quot;));&lt;br /&gt;
 pict.writeToFile (tempFile);&lt;br /&gt;
 GraphicsImporter importer = new GraphicsImporter (tempFile);&lt;br /&gt;
&lt;br /&gt;
With the pict imported into a &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt;, you would get a &amp;lt;tt&amp;gt;QTImageProducer&amp;lt;/tt&amp;gt; from the &amp;lt;tt&amp;gt;GraphicsImporterDrawer&amp;lt;/tt&amp;gt; and generate AWT &amp;lt;tt&amp;gt;Image&amp;lt;/tt&amp;gt;s from the image producer, without messing up the movie playback.&lt;br /&gt;
&lt;br /&gt;
The drawback of this approach is that you must read and write data to the hard drive, which is obviously much slower than an operation that takes place purely in memory.&lt;br /&gt;
&lt;br /&gt;
In fact, an in-memory equivalent is possible. Look back at the &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt; Javadoc. Several &amp;lt;tt&amp;gt;setData( )&amp;lt;/tt&amp;gt; methods allow you to use sources other than just flat files for input to a &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt;. Two of them allow you to pass in more or less opaque pointers: &amp;lt;tt&amp;gt;setDataReference()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;setDataHandle()&amp;lt;/tt&amp;gt;. With these calls, the importer will read from memory the same way it would read from disk.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''And they say Java doesn't have pointers!''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The trick in this case is to make the &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt; think it's reading a ''.pict'' file from disk, but actually it's reading from memory. One gotcha in this case is that pict files have a 512-byte header before their data—the header doesn't have to contain anything meaningful, it just has to be present. So, allocate a byte array 512 bytes longer than the size of the &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt; data (&amp;lt;tt&amp;gt;getSize()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;getBytes( )&amp;lt;/tt&amp;gt;, inherited from &amp;lt;tt&amp;gt;QTHandleRef&amp;lt;/tt&amp;gt;, respectively, return the size and contents of the native structure pointed to by the &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt; object, not the Java object itself), and copy those bytes over with an offset of 512.&lt;br /&gt;
&lt;br /&gt;
Next, you need a &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt; for the &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt; format, and a &amp;lt;tt&amp;gt;GraphicsImporterDrawer&amp;lt;/tt&amp;gt; to provide the &amp;lt;tt&amp;gt;QTImageProducer&amp;lt;/tt&amp;gt;. The example code creates these in its constructor:&lt;br /&gt;
&lt;br /&gt;
 // set up graphicsimporter&lt;br /&gt;
 gi = new GraphicsImporter (StdQTConstants.kQTFileTypePicture);&lt;br /&gt;
 gid = new GraphicsImporterDrawer (gi);&lt;br /&gt;
&lt;br /&gt;
Build a &amp;lt;tt&amp;gt;DataRef&amp;lt;/tt&amp;gt; to point to the byte array and pass it to the &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt; with &amp;lt;tt&amp;gt;setDataReference( )&amp;lt;/tt&amp;gt;. You've now replaced the file write and file read with equivalent in-memory operations. Now it's a simple matter of getting a &amp;lt;tt&amp;gt;GraphicsImporterDrawer&amp;lt;/tt&amp;gt; and, from that, a &amp;lt;tt&amp;gt;QTImageProducer&amp;lt;/tt&amp;gt; to create Java images.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
This technique is adapted from &amp;quot;Technical Q&amp;amp;A QTMTB56: Importing Image Data from Memory,&amp;quot; at ''http://developer.apple.com/qa/qtmtb/qtmtb56.html''. Check it out for a comparison of QTJ versus straight-C QuickTime coding styles.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Drawing with Graphics Primitives ==&lt;br /&gt;
&lt;br /&gt;
In AWT, a &amp;lt;tt&amp;gt;Graphics&amp;lt;/tt&amp;gt; object represents a drawing surface—either on-screen or off-screen—and supplies various methods for drawing on it. QuickTime has a &amp;lt;tt&amp;gt;GWorld&amp;lt;/tt&amp;gt; object that's so similar, the QT developers renamed it &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt; just to make Java developers feel at home. As with the AWT class, painting is driven by a callback mentality.&lt;br /&gt;
&lt;br /&gt;
=== How do I do that? ===&lt;br /&gt;
&lt;br /&gt;
[[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-EX-4|Example 5-4]] shows the &amp;lt;tt&amp;gt;GWorldToPict&amp;lt;/tt&amp;gt; example, which creates a &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt; object and performs some simple drawing operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-EX-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 5-4. Drawing on a QDGraphics object'''&lt;br /&gt;
&lt;br /&gt;
 package com.oreilly.qtjnotebook.ch05;&lt;br /&gt;
  &lt;br /&gt;
 import quicktime.*;&lt;br /&gt;
 import quicktime.std.*;&lt;br /&gt;
 import quicktime.std.image.*;&lt;br /&gt;
 import quicktime.qd.*;&lt;br /&gt;
  &lt;br /&gt;
 import com.oreilly.qtjnotebook.ch01.QTSessionCheck;&lt;br /&gt;
  &lt;br /&gt;
 public class GWorldToPict extends Object implements QDDrawer {&lt;br /&gt;
  &lt;br /&gt;
   public static void main (String[  ] args) {&lt;br /&gt;
       new GWorldToPict( );&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   public GWorldToPict( ) {&lt;br /&gt;
       try {&lt;br /&gt;
           QTSessionCheck.check( );&lt;br /&gt;
           QDRect bounds = new QDRect (0, 0, 200, 250);&lt;br /&gt;
           ImageDescription imgDesc =&lt;br /&gt;
               new ImageDescription(QDConstants.k32RGBAPixelFormat);&lt;br /&gt;
           imgDesc.setHeight (bounds.getHeight( ));&lt;br /&gt;
           imgDesc.setWidth (bounds.getWidth( ));&lt;br /&gt;
           QDGraphics gw = new QDGraphics (imgDesc, 0);&lt;br /&gt;
           System.out.println (&amp;quot;GWorld created: &amp;quot; + gw);&lt;br /&gt;
           &lt;br /&gt;
           OpenCPicParams params = new OpenCPicParams(bounds);&lt;br /&gt;
  &lt;br /&gt;
           Pict pict = Pict.open (gw, params);&lt;br /&gt;
           gw.beginDraw (this);&lt;br /&gt;
  &lt;br /&gt;
           pict.close( );&lt;br /&gt;
  &lt;br /&gt;
           try {&lt;br /&gt;
               pict.writeToFile (new java.io.File (&amp;quot;gworld.pict&amp;quot;));&lt;br /&gt;
           } catch (java.io.IOException ioe) {&lt;br /&gt;
               ioe.printStackTrace( );&lt;br /&gt;
           }&lt;br /&gt;
       } catch (QTException qte) {&lt;br /&gt;
           qte.printStackTrace( );&lt;br /&gt;
       }&lt;br /&gt;
       System.exit(0);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   public void draw (QDGraphics gw) throws QTException {&lt;br /&gt;
       System.out.println (&amp;quot;draw( ) called with GWorld &amp;quot; + gw);&lt;br /&gt;
       QDRect bounds = gw.getBounds( );&lt;br /&gt;
       System.out.println (&amp;quot;bounds: &amp;quot; + bounds);&lt;br /&gt;
       // clear drawing surface, set up colors&lt;br /&gt;
       gw.setBackColor (QDColor.lightGray);&lt;br /&gt;
       gw.eraseRect (bounds);&lt;br /&gt;
       // draw some shapes&lt;br /&gt;
       gw.penSize (2, 2);&lt;br /&gt;
       gw.moveTo (20,20);&lt;br /&gt;
       gw.setForeColor (QDColor.green);&lt;br /&gt;
       gw.line (30, 100);&lt;br /&gt;
       gw.moveTo (20,20);&lt;br /&gt;
       gw.setForeColor (QDColor.blue);&lt;br /&gt;
       gw.lineTo (30, 100);&lt;br /&gt;
  &lt;br /&gt;
       // draw some text&lt;br /&gt;
       gw.setForeColor (QDColor.red);&lt;br /&gt;
       gw.textSize (24);&lt;br /&gt;
       gw.moveTo (10, 150);&lt;br /&gt;
       gw.drawText (&amp;quot;QDGraphics&amp;quot;, 0, 10);&lt;br /&gt;
  &lt;br /&gt;
       // draw some shapes&lt;br /&gt;
       gw.setForeColor (QDColor.magenta);&lt;br /&gt;
       QDRect rect = new QDRect (0, 170, 40, 30);&lt;br /&gt;
       gw.paintRoundRect (rect, 0, 0);&lt;br /&gt;
       QDRect roundRect = new QDRect (50, 170, 40, 30);&lt;br /&gt;
       gw.paintRoundRect (roundRect, 10, 10);&lt;br /&gt;
       QDRect ovalRect = new QDRect (100, 170, 40, 30);&lt;br /&gt;
       gw.paintOval (ovalRect);&lt;br /&gt;
       QDRect arcRect = new QDRect (150, 170, 40, 30);&lt;br /&gt;
       gw.paintArc (arcRect, 15, 215);&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a headless application. When run, it does its imaging off-screen and writes the file to ''gworld.pict''. Open this file in a pict-aware editor or viewer to see the output, as shown in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-FIG-4|Figure 5-4]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-FIG-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-4. Graphics primitives drawn with QDGraphics'''&lt;br /&gt;
&lt;br /&gt;
[[Image:QuickTime for Java: A Developer's Notebook_I_5_tt73.png|Graphics primitives drawn with QDGraphics]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What just happened? ===&lt;br /&gt;
&lt;br /&gt;
The program sets up an &amp;lt;tt&amp;gt;ImageDescription&amp;lt;/tt&amp;gt;, specifying a color model and size information, and creates a &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt; drawing surface according to its specs. Next, a new &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt; is created from the &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt; and an object called &amp;lt;tt&amp;gt;OpenCPicParams&amp;lt;/tt&amp;gt;, which provides size and resolution information. For on-screen work, the default 72dpi is fine.&lt;br /&gt;
&lt;br /&gt;
Next, it issues a &amp;lt;tt&amp;gt;Pict.beginDraw()&amp;lt;/tt&amp;gt; command, passing in a &amp;lt;tt&amp;gt;QDDrawer&amp;lt;/tt&amp;gt; object. &amp;lt;tt&amp;gt;QDDrawer&amp;lt;/tt&amp;gt; is an interface for setting up callbacks to a &amp;lt;tt&amp;gt;draw()&amp;lt;/tt&amp;gt; method that specifies the &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt; to be drawn on. This redraw-oriented API is kind of overkill for this headless, off-screen example, but it does get the job done. The &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt; records the drawing commands made in the &amp;lt;tt&amp;gt;draw( )&amp;lt;/tt&amp;gt; call and saves the result to disk as ''gworld.pict''.&lt;br /&gt;
&lt;br /&gt;
So, what can you do with &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt; primitives? Some basics of geometry are shown in this example. &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt; work with a system of foreground and background colors, a pen of some number of horizontal and vertical pixels, and a concept of a current position. This example begins with two variants of line drawing: the first drawing a line specified by an offset in horizontal and vertical pixels, and the second drawing a line to a specific point. Next, it draws some text in the default font—note that as with AWT, the text will go above the current point. Finally, the example iterates through some of the simpler shapes available as graphics primitives: ovals, optionally rounded rectangles, and arcs.&lt;br /&gt;
&lt;br /&gt;
=== What about . . . ===&lt;br /&gt;
&lt;br /&gt;
. . . drawing an image into the &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt;, like with AWT's &amp;lt;tt&amp;gt;Graphics.drawImage( )&amp;lt;/tt&amp;gt; ? Ah, you're getting ahead of me. That will be covered later in the chapter.&lt;br /&gt;
&lt;br /&gt;
Also, why are all the variables and comments here &amp;lt;tt&amp;gt;GWorld&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;gw&amp;lt;/tt&amp;gt; instead of &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;qdg&amp;lt;/tt&amp;gt;? Like I said at the start of this lab, &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt; is something of an analogy to an AWT &amp;lt;tt&amp;gt;Graphics&amp;lt;/tt&amp;gt;. Unfortunately, it's a flawed analogy. It wraps a native drawing surface called a &amp;lt;tt&amp;gt;GWorld&amp;lt;/tt&amp;gt; , and all the calls throughout QTJ that take or return it use the &amp;quot;GWorld&amp;quot; verbiage, such as the &amp;lt;tt&amp;gt;setGWorld( )&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;getGWorld( )&amp;lt;/tt&amp;gt; calls that you'll see throughout the Javadoc. Once you start getting into QTJ, the desire to understand it from QuickTime's point of view, as a &amp;lt;tt&amp;gt;GWorld&amp;lt;/tt&amp;gt;, outweighs the benefits of making an appeal to the AWT &amp;lt;tt&amp;gt;Graphics&amp;lt;/tt&amp;gt; analogy. So, to me, it's a &amp;lt;tt&amp;gt;GWorld&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Getting a Screen Capture ==&lt;br /&gt;
&lt;br /&gt;
One frequently useful source of image data is, unsurprisingly, the screen—or screens, if you're so fortunate. Each screen is represented by an object that can give you its current contents, though it takes a little work to do anything with it.&lt;br /&gt;
&lt;br /&gt;
=== How do I do that? ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;ScreenToPNG&amp;lt;/tt&amp;gt;, shown in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-EX-5|Example 5-5]], is a headless application that starts up, grabs the screen, and writes out the image to a PNG file called ''screen.png''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''I use PNG for screenshots because it's lossless, widely supported, compressed, and patent-unencumbered''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-EX-5&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 5-5. Grabbing screen pixels'''&lt;br /&gt;
&lt;br /&gt;
 package com.oreilly.qtjnotebook.ch05;&lt;br /&gt;
  &lt;br /&gt;
 import quicktime.*;&lt;br /&gt;
 import quicktime.std.*;&lt;br /&gt;
 import quicktime.std.image.*;&lt;br /&gt;
 import quicktime.qd.*;&lt;br /&gt;
 import quicktime.io.*;&lt;br /&gt;
 import quicktime.util.*;&lt;br /&gt;
  &lt;br /&gt;
 import com.oreilly.qtjnotebook.ch01.QTSessionCheck;&lt;br /&gt;
  &lt;br /&gt;
 public class ScreenToPNG extends Object  {&lt;br /&gt;
  &lt;br /&gt;
   public static void main (String[  ] args) {&lt;br /&gt;
       new ScreenToPNG( );&lt;br /&gt;
   }&lt;br /&gt;
  &lt;br /&gt;
   public ScreenToPNG( ) {&lt;br /&gt;
       try {&lt;br /&gt;
           QTSessionCheck.check( );&lt;br /&gt;
  &lt;br /&gt;
           GDevice gd = GDevice.getMain( );&lt;br /&gt;
           System.out.println (&amp;quot;Got GDevice: &amp;quot; + gd);&lt;br /&gt;
           PixMap pm = gd.getPixMap( );&lt;br /&gt;
           System.out.println (&amp;quot;Got PixMap: &amp;quot; + pm);&lt;br /&gt;
           ImageDescription id = new ImageDescription (pm);&lt;br /&gt;
           System.out.println (&amp;quot;Got ImageDescription: &amp;quot; + id);&lt;br /&gt;
           QDRect bounds = pm.getBounds( );&lt;br /&gt;
           RawEncodedImage rei = pm.getPixelData( );&lt;br /&gt;
  &lt;br /&gt;
           QDGraphics decompGW = new QDGraphics (id, 0);&lt;br /&gt;
           QTImage.decompress (rei,&lt;br /&gt;
                               id,&lt;br /&gt;
                               decompGW,&lt;br /&gt;
                               bounds,&lt;br /&gt;
                               0);&lt;br /&gt;
  &lt;br /&gt;
           GraphicsExporter exporter =&lt;br /&gt;
               new GraphicsExporter (StdQTConstants4.kQTFileTypePNG);&lt;br /&gt;
           exporter.setInputPixmap (decompGW);&lt;br /&gt;
           QTFile outFile = new QTFile (new java.io.File (&amp;quot;screen.png&amp;quot;));&lt;br /&gt;
           exporter.setOutputFile (outFile);&lt;br /&gt;
           System.out.println (&amp;quot;Exported &amp;quot; + &lt;br /&gt;
                               exporter.doExport( ) +&lt;br /&gt;
                               &amp;quot; bytes&amp;quot;);&lt;br /&gt;
           &lt;br /&gt;
       } catch (QTException qte) {&lt;br /&gt;
           qte.printStackTrace( );&lt;br /&gt;
       }&lt;br /&gt;
       System.exit(0);&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When finished, open the ''screen.png'' file with your favorite image editor or browser. A shot of my iBook's screen while writing the demo is shown in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-FIG-5|Figure 5-5]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-FIG-5&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-5. Screen capture'''&lt;br /&gt;
&lt;br /&gt;
[[Image:QuickTime for Java: A Developer's Notebook_I_5_tt74.png|Screen capture]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice at the bottom left that I have the DVD Player application running. Apple's tools for doing screen grabs—the Grab application and the Cmd-Shift-3 and Cmd-Shift-4 key combinations—won't work if you have the DVD Player running. However, this proves that those pixels are available to QuickDraw. That said, if you grab the screen while a DVD is playing, you might get ''tearing'' (if the capture grabs between frames) or even a blank panel (if the capture catches the repaint at a bad time). If you're going to use this to grab images from DVDs, hit Pause first.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''Also, don't do anything with a DVD that will get you or me sued''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What just happened? ===&lt;br /&gt;
&lt;br /&gt;
The program asks for the main screen by means of the static &amp;lt;tt&amp;gt;GDevice.getMain( )&amp;lt;/tt&amp;gt; method. From this, you can get a &amp;lt;tt&amp;gt;PixMap&amp;lt;/tt&amp;gt; , which is an object that represents metadata about a stored image, such as its color table, pixel format, packing scheme, etc. This metadata also can be stored as an &amp;lt;tt&amp;gt;ImageDescription&amp;lt;/tt&amp;gt;, which is a structure that many graphics methods take as a parameter. The &amp;lt;tt&amp;gt;PixMap&amp;lt;/tt&amp;gt; also has a pointer to the byte array that holds the image data, which you can retrieve as the wrapper object &amp;lt;tt&amp;gt;RawEncodedImage&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''Java 2D analogy: a PixMap is like a Raster, an ImageDescription is like a Sample-Model, and an EncodedImage is like a DataBuffer. Not exactly the same, but the same ideas throughout''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So now you have an image of what's on the screen—what can you do with it? The goal is to get that image into a format suitable for a &amp;lt;tt&amp;gt;GraphicsExporter&amp;lt;/tt&amp;gt;. One means of doing this is to render into a &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt; and send that to the exporter. To do this, look to the &amp;lt;tt&amp;gt;QTImage&amp;lt;/tt&amp;gt; class, which has methods to compress (from a &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt; drawing surface to an &amp;lt;tt&amp;gt;EncodedImage&amp;lt;/tt&amp;gt;) and decompress (from a possibly compressed &amp;lt;tt&amp;gt;EncodedImage&amp;lt;/tt&amp;gt; to a &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt;). In this case, use &amp;lt;tt&amp;gt;decompress( )&amp;lt;/tt&amp;gt; to make a &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt;, then pass that to the exporter's &amp;lt;tt&amp;gt;setInputPixMap( )&amp;lt;/tt&amp;gt; method (yes, despite the name, it takes a &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt;, not a &amp;lt;tt&amp;gt;PixMap&amp;lt;/tt&amp;gt;) and do the export.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
It's odd that &amp;lt;tt&amp;gt;EncodedImage&amp;lt;/tt&amp;gt; is an interface, yet its relevant methods, like &amp;lt;tt&amp;gt;decompress( )&amp;lt;/tt&amp;gt;, are static in &amp;lt;tt&amp;gt;QTImage&amp;lt;/tt&amp;gt; (which is in another package!). Maybe &amp;lt;tt&amp;gt;EncodedImage&amp;lt;/tt&amp;gt; should have been an abstract class?&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What about . . . ===&lt;br /&gt;
&lt;br /&gt;
. . . getting other screens? If you do have multiple monitors, &amp;lt;tt&amp;gt;GDevice&amp;lt;/tt&amp;gt; has a scheme for iterating through the screens. Call the static &amp;lt;tt&amp;gt;GDevice.getList( )&amp;lt;/tt&amp;gt; to get—wait for it—not a list of &amp;lt;tt&amp;gt;GDevice&amp;lt;/tt&amp;gt;s, but just the first one. You then call its instance method &amp;lt;tt&amp;gt;getNext( )&amp;lt;/tt&amp;gt; to return another &amp;lt;tt&amp;gt;GDevice&amp;lt;/tt&amp;gt;, and so on, until &amp;lt;tt&amp;gt;getNext()&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;null&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
And why is the PNG file-type constant defined in &amp;lt;tt&amp;gt;StdQTConstants4&amp;lt;/tt&amp;gt; ? PNG came late to the QuickTime party and wasn't supported until QuickTime 4. The later constants classes (&amp;lt;tt&amp;gt;StdQTContants4&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;StdQTContants5&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;StdQTContants6&amp;lt;/tt&amp;gt;) define constants that were added in later versions of QuickTime. &amp;lt;tt&amp;gt;kQTFileTypeTIFF&amp;lt;/tt&amp;gt; is also in &amp;lt;tt&amp;gt;StdQTConstants4&amp;lt;/tt&amp;gt;, but most other values you'd want to use are in the original &amp;lt;tt&amp;gt;StdQTConstants&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Also, it's getting difficult to remember the various means of converting between &amp;lt;tt&amp;gt;EncodedImage&amp;lt;/tt&amp;gt;s, &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt;s, &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt;, etc. To keep track of all this for myself, I created the diagram in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-FIG-6|Figure 5-6]] while writing this chapter and have found myself consulting it frequently since then.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-FIG-6&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-6. Converting between QuickDraw objects'''&lt;br /&gt;
&lt;br /&gt;
[[Image:QuickTime for Java: A Developer's Notebook_I_5_tt75.png|Converting between QuickDraw objects]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''Why, oh why, are these methods named like this?''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Matrix-Based Drawing ==&lt;br /&gt;
&lt;br /&gt;
Primitives and copying blocks of pixels are nice, but they're kind of limiting. Oftentimes, you must take pixels and scale them, rotate them, and move them around. Of course, if you've worked with Java 2D, you know this as the concept of ''affine transformations'' , which maps one set of pixels to another set of pixels, keeping straight lines straight and parallel lines parallel.&lt;br /&gt;
&lt;br /&gt;
If you've really worked with Java 2D's affine transformations, you probably know that they're represented as a linear algebra matrix, with coordinates mapped from source to destination by multiplying and/or adding pixel values against coefficients of the matrix. By changing the coefficients in the matrix to interesting values (or trigonometric functions), you can define different kinds of transformations.&lt;br /&gt;
&lt;br /&gt;
QuickTime does exactly the same thing, with the minor exception that rather than hiding the matrix in a wrapper (like J2D's &amp;lt;tt&amp;gt;AffineTransformation&amp;lt;/tt&amp;gt; class), it puts the matrix front-and-center throughout the API. One reason for this is that it's also a major part of the file format—tracks in a movie all have a matrix in their metadata to determine how they're rendered at runtime.&lt;br /&gt;
&lt;br /&gt;
QuickTime matrix manipulation can basically do three things for you:&lt;br /&gt;
&lt;br /&gt;
;Translation&lt;br /&gt;
: Move a block of pixels from one location to another&lt;br /&gt;
;Rotation&lt;br /&gt;
: Rotate pixels around a given point&lt;br /&gt;
;Scaling&lt;br /&gt;
: Make block bigger or smaller, or change its shape&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
This is a lab, not a lecture, so you don't get the all-singing, all-dancing, all-algebra introduction to matrix theory here. If you must have this, Apple provides a pretty straightforward intro in &amp;quot;The Transformation Matrix,&amp;quot; part of the &amp;quot;Introductions to QuickTime&amp;quot; documentation anthology on its web site.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How do I do that? ===&lt;br /&gt;
&lt;br /&gt;
The example &amp;lt;tt&amp;gt;GraphicImportMatrix&amp;lt;/tt&amp;gt; shows the effect of setting up a &amp;lt;tt&amp;gt;Matrix&amp;lt;/tt&amp;gt; and then using it for drawing operations. A full listing is in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-EX-6|Example 5-6]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''Run this example with ant run-ch05-graphic-importmatrix''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-EX-6&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 5-6. Drawing with matrix-based transformations'''&lt;br /&gt;
&lt;br /&gt;
 package com.oreilly.qtjnotebook.ch05;&lt;br /&gt;
 &lt;br /&gt;
 import quicktime.*;&lt;br /&gt;
 import quicktime.std.*;&lt;br /&gt;
 import quicktime.std.image.*;&lt;br /&gt;
 import quicktime.qd.*;&lt;br /&gt;
 import quicktime.io.*;&lt;br /&gt;
 import quicktime.util.*;&lt;br /&gt;
 import quicktime.app.view.*;&lt;br /&gt;
 import java.io.*;&lt;br /&gt;
 import java.awt.*;&lt;br /&gt;
 &lt;br /&gt;
 import com.oreilly.qtjnotebook.ch01.QTSessionCheck;&lt;br /&gt;
 &lt;br /&gt;
 public class GraphicImportMatrix extends Object {&lt;br /&gt;
 &lt;br /&gt;
  public static void main (String[  ] args) {&lt;br /&gt;
    try {&lt;br /&gt;
        QTSessionCheck.check( );&lt;br /&gt;
 &lt;br /&gt;
        File graphicsDir = new File (&amp;quot;graphics&amp;quot;);&lt;br /&gt;
        QTFile pngFile1 = new QTFile (new File (graphicsDir, &amp;quot;1.png&amp;quot;));&lt;br /&gt;
        QTFile pngFile2 = new QTFile (new File (graphicsDir, &amp;quot;2.png&amp;quot;));&lt;br /&gt;
        GraphicsImporter gi1 = new GraphicsImporter (pngFile1);&lt;br /&gt;
        GraphicsImporter gi2 = new GraphicsImporter (pngFile2);&lt;br /&gt;
        &lt;br /&gt;
        // define some matrix transforms on importer 1&lt;br /&gt;
        QDRect bounds = gi1.getBoundsRect( );&lt;br /&gt;
        // combine translation (movement) and scaling into&lt;br /&gt;
        // one call to rect&lt;br /&gt;
        QDRect newBounds =&lt;br /&gt;
            new QDRect (bounds.getWidth( )/4,&lt;br /&gt;
                        bounds.getHeight( )/4,&lt;br /&gt;
                        bounds.getWidth( )/2,&lt;br /&gt;
                        bounds.getHeight( )/2);&lt;br /&gt;
        Matrix matrix = new Matrix( );&lt;br /&gt;
        matrix.rect(bounds, newBounds);&lt;br /&gt;
        // rotate about its center&lt;br /&gt;
        matrix.rotate (30,&lt;br /&gt;
                       (bounds.getWidth( ) - bounds.getX( ))/2,&lt;br /&gt;
                       (bounds.getHeight( ) - bounds.getY( ))/2);&lt;br /&gt;
        gi1.setMatrix (matrix);&lt;br /&gt;
 &lt;br /&gt;
        // draw somewhere&lt;br /&gt;
        QDGraphics scratchWorld = new QDGraphics (gi2.getBoundsRect( ));&lt;br /&gt;
        System.out.println (&amp;quot;Scratch world: &amp;quot; + scratchWorld);&lt;br /&gt;
        // draw background&lt;br /&gt;
        gi2.setGWorld (scratchWorld, null);&lt;br /&gt;
        gi2.draw( );&lt;br /&gt;
        // draw foreground&lt;br /&gt;
        gi1.setGWorld (scratchWorld, null);&lt;br /&gt;
        gi1.draw( );&lt;br /&gt;
 &lt;br /&gt;
        int bufSize =&lt;br /&gt;
            QTImage.getMaxCompressionSize (scratchWorld, &lt;br /&gt;
                                           scratchWorld.getBounds( ),&lt;br /&gt;
                                           0,&lt;br /&gt;
                                           StdQTConstants.codecNormalQuality,&lt;br /&gt;
                                           StdQTConstants4.kPNGCodecType,&lt;br /&gt;
                                           CodecComponent.anyCodec);&lt;br /&gt;
        byte[  ] compBytes = new byte[bufSize];&lt;br /&gt;
        RawEncodedImage compImg = new RawEncodedImage (compBytes);&lt;br /&gt;
        ImageDescription id =&lt;br /&gt;
            QTImage.compress(scratchWorld,&lt;br /&gt;
                            scratchWorld.getBounds( ),&lt;br /&gt;
                            StdQTConstants.codecNormalQuality,&lt;br /&gt;
                            StdQTConstants4.kPNGCodecType,&lt;br /&gt;
                            compImg);&lt;br /&gt;
        System.out.println (&amp;quot;rei compressed from gw is &amp;quot; +&lt;br /&gt;
                            compImg.getSize( ));&lt;br /&gt;
 &lt;br /&gt;
        System.out.println (&amp;quot;exporting&amp;quot;);&lt;br /&gt;
        GraphicsExporter exporter =&lt;br /&gt;
            new GraphicsExporter (StdQTConstants4.kQTFileTypePNG);&lt;br /&gt;
        exporter.setInputPtr (compImg, id);&lt;br /&gt;
        QTFile outFile = new QTFile (new File (&amp;quot;matrix.png&amp;quot;));&lt;br /&gt;
        exporter.setOutputFile (outFile);&lt;br /&gt;
        exporter.doExport( );&lt;br /&gt;
        System.out.println (&amp;quot;did export&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
    } catch (QTException qte) {&lt;br /&gt;
        qte.printStackTrace( );&lt;br /&gt;
    }&lt;br /&gt;
    System.exit(0);&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''Run this example with ant run-ch05-screentopng''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This headless app begins by importing two PNG files, the number ''1'' on a green background and the number ''2'' on cyan. Then it creates a &amp;lt;tt&amp;gt;GWorld&amp;lt;/tt&amp;gt; (oops, I mean a &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt;—sorry!) big enough to hold the ''2'' image, which will serve as the background. Both &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt;s call &amp;lt;tt&amp;gt;setGWorld()&amp;lt;/tt&amp;gt; with the &amp;lt;tt&amp;gt;scratchWorld&amp;lt;/tt&amp;gt;, which allows them to &amp;lt;tt&amp;gt;draw( )&amp;lt;/tt&amp;gt; into it. A &amp;lt;tt&amp;gt;Matrix&amp;lt;/tt&amp;gt; defines a scale, translate, and rotate transformation for the ''1'', which is drawn atop the ''2''. The result is compressed as a PNG and saved as ''matrix.png'', which is shown in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-FIG-7|Figure 5-7]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-FIG-7&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-7. Drawing with a Matrix'''&lt;br /&gt;
&lt;br /&gt;
[[Image:QuickTime for Java: A Developer's Notebook_I_5_tt76.png|Drawing with a Matrix]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What just happened? ===&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;tt&amp;gt;setMatrix( )&amp;lt;/tt&amp;gt; with a &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt; allows you to tell the importer to use the transformation specified by the &amp;lt;tt&amp;gt;Matrix&amp;lt;/tt&amp;gt; when you call the importer's &amp;lt;tt&amp;gt;draw( )&amp;lt;/tt&amp;gt; method. Of the three typical transformations, two can be combined into one call—scaling and translating can be expressed with a single call, &amp;lt;tt&amp;gt;Matrix.rect()&amp;lt;/tt&amp;gt; , which defines a mapping from one source rectangle to a target rectangle. In the example, &amp;lt;tt&amp;gt;rect( )&amp;lt;/tt&amp;gt; maps from the full size of the image to a quarter-size image, centered horizontally and vertically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
The same thing can be done with separate calls to &amp;lt;tt&amp;gt;Matrix.translate( )&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Matrix.scale()&amp;lt;/tt&amp;gt;, if you prefer.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The example also calls &amp;lt;tt&amp;gt;Matrix.rotate()&amp;lt;/tt&amp;gt; to rotate the scaled and moved box by 30 degrees clockwise.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;tip&amp;quot;&amp;gt;&lt;br /&gt;
'''Tip'''&lt;br /&gt;
&lt;br /&gt;
You also can define matrix transformations by calling the various &amp;lt;tt&amp;gt;setXXX( )&amp;lt;/tt&amp;gt; methods that set individual coordinates in the &amp;lt;tt&amp;gt;Matrix&amp;lt;/tt&amp;gt;, if you've read Apple's Matrix docs and understand each coefficient. But why bother when you've got the convenience calls?&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Having set this &amp;lt;tt&amp;gt;Matrix&amp;lt;/tt&amp;gt; on ''1'''s &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt;, the example draws ''2'' into &amp;lt;tt&amp;gt;scratchWorld&amp;lt;/tt&amp;gt; as a background, and then draws ''1'' on top of it, scaled, translated, and rotated.&lt;br /&gt;
&lt;br /&gt;
But what to do with the pixels that have been drawn into the &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt;? It's not like the [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#Drawing with Graphics Primitives|Section 5.5]] lab, in which a &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt; was wrapped by a &amp;lt;tt&amp;gt;Pict&amp;lt;/tt&amp;gt; that could be saved off to disk. Instead, use &amp;lt;tt&amp;gt;QTImage&amp;lt;/tt&amp;gt; to create an &amp;lt;tt&amp;gt;EncodedImage&amp;lt;/tt&amp;gt; from the drawing surface. In the [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#Getting a Screen Capture|Section 5.6]] lab, &amp;lt;tt&amp;gt;QTImage.decompress( )&amp;lt;/tt&amp;gt; converted an image to a &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt;. In this case, &amp;lt;tt&amp;gt;QTImage.compress( )&amp;lt;/tt&amp;gt; can return the favor by compressing the possibly huge pixel map into a compressed format.&lt;br /&gt;
&lt;br /&gt;
Compressing is harder than decompressing. You need to know up front how big of a byte array will be needed to hold the compressed bytes, so first you call &amp;lt;tt&amp;gt;getMaxCompressionSize()&amp;lt;/tt&amp;gt; . This takes six parameters:&lt;br /&gt;
&lt;br /&gt;
* A &amp;lt;tt&amp;gt;QDGraphics&amp;lt;/tt&amp;gt; to compress from.&lt;br /&gt;
* A &amp;lt;tt&amp;gt;QDRect&amp;lt;/tt&amp;gt; defining the region to be compressed.&lt;br /&gt;
* Color depth, as an &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Set this to &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; to let QuickTime decide.&lt;br /&gt;
* Codec quality. These are in &amp;lt;tt&amp;gt;StdQTConstants&amp;lt;/tt&amp;gt; . From the worst to best, they are: &amp;lt;tt&amp;gt;codecMinQuality&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;codecLowQuality&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;codecNormalQuality&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;codecHighQuality&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;codecMaxQuality&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;codecLosslessQuality&amp;lt;/tt&amp;gt;. Note that not all codecs support all these values.&lt;br /&gt;
* Codec type. These constants are identified as &amp;lt;tt&amp;gt;XXXCodecType&amp;lt;/tt&amp;gt; constants in the &amp;lt;tt&amp;gt;StdQTConstants&amp;lt;/tt&amp;gt; classes.&lt;br /&gt;
* Codec identifier. If you have a &amp;lt;tt&amp;gt;CodecComponent&amp;lt;/tt&amp;gt; object you want to use for the compression, pass it here. Typically, you pass &amp;lt;tt&amp;gt;null&amp;lt;/tt&amp;gt; to let QuickTime decide.&lt;br /&gt;
&lt;br /&gt;
Most of these parameters are used in the subsequent &amp;lt;tt&amp;gt;compress( )&amp;lt;/tt&amp;gt; call. It goes without saying that you need to use the same values for each call, or else &amp;lt;tt&amp;gt;getMaxCompressionSize( )&amp;lt;/tt&amp;gt; will lead you to create a byte array that is the wrong size.&lt;br /&gt;
&lt;br /&gt;
Along with many of the preceding parameters, the &amp;lt;tt&amp;gt;compress()&amp;lt;/tt&amp;gt; call takes a &amp;lt;tt&amp;gt;RawEncodedImage&amp;lt;/tt&amp;gt; created from a suitably large byte array. &amp;lt;tt&amp;gt;compress( )&amp;lt;/tt&amp;gt; puts the compressed and encoded image data into the &amp;lt;tt&amp;gt;RawEncodedImage&amp;lt;/tt&amp;gt; and returns an &amp;lt;tt&amp;gt;ImageDescription&amp;lt;/tt&amp;gt;. Taken together, these are enough to provide an input to a &amp;lt;tt&amp;gt;GraphicsExporter&amp;lt;/tt&amp;gt;, in the form of a call to &amp;lt;tt&amp;gt;setInputPtr()&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''Passing pointers again! This is one of those cases where QTJ is very un-Java-like''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Compositing Graphics ==&lt;br /&gt;
&lt;br /&gt;
Matrix transformations are nice, but you can do more with image drawing. QuickDraw supports a number of ''graphics modes'' so that instead of just copying pixels from a source to a destination, you can combine them to create interesting visual effects. The graphics mode defines the combination: blending, translucency, etc.&lt;br /&gt;
&lt;br /&gt;
=== How do I do that? ===&lt;br /&gt;
&lt;br /&gt;
Specifying a graphics mode for drawing is trivial. Create a &amp;lt;tt&amp;gt;GraphicsMode&amp;lt;/tt&amp;gt; object and call &amp;lt;tt&amp;gt;setGraphicsMode( )&amp;lt;/tt&amp;gt; on the &amp;lt;tt&amp;gt;GraphicsImporter&amp;lt;/tt&amp;gt;. In the included example, ''GraphicImportCompositing.java'', the mode is set with the following code:&lt;br /&gt;
&lt;br /&gt;
 // draw foreground&lt;br /&gt;
 GraphicsMode alphaMode =&lt;br /&gt;
   new GraphicsMode (QDConstants.blend,&lt;br /&gt;
                     QDColor.green);&lt;br /&gt;
 gi1.setGraphicsMode (alphaMode);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
''Run this with ant-ch05-graphic-importcompositing''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is another headless app, producing the ''composite.png'' file as shown in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-FIG-8|Figure 5-8]]. Notice that where the images overlap, the ''2'' can now show through the ''1''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-FIG-8&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-8. Drawing with blend graphics mode'''&lt;br /&gt;
&lt;br /&gt;
[[Image:QuickTime for Java: A Developer's Notebook_I_5_tt78.png|Drawing with blend graphics mode]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== What just happened? ===&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;blend&amp;quot; &amp;lt;tt&amp;gt;GraphicsMode&amp;lt;/tt&amp;gt; instructs QuickDraw to average out colors where they overlap. In this case, ''1'''s black pixels are lightened up by averaging when averaged with cyan, and the green is slightly tinted where it overlaps with cyan or black.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;QDColor.green&amp;lt;/tt&amp;gt; is irrelevant in this case, but change the first argument to &amp;lt;tt&amp;gt;QDConstants.transparent&amp;lt;/tt&amp;gt; and suddenly the result is very different, as shown in [[QuickTime for Java: A Developer's Notebook/Working with QuickDraw#quicktimejvaadn-CHP-5-FIG-9|Figure 5-9]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;quicktimejvaadn-CHP-5-FIG-9&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 5-9. Drawing with transparent graphics mode'''&lt;br /&gt;
&lt;br /&gt;
[[Image:QuickTime for Java: A Developer's Notebook_I_5_tt79.png|Drawing with transparent graphics mode]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;tt&amp;gt;GraphicsMode&amp;lt;/tt&amp;gt; takes a constant to specify behavior, and a color that is used by ''some'' of the available modes. In the case of &amp;lt;tt&amp;gt;transparent&amp;lt;/tt&amp;gt;, any pixels of the specified color (green in this case) become invisible, allowing the background picture to show through.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Warning'''&lt;br /&gt;
&lt;br /&gt;
Don't jump to the conclusion that this is similar to transparency in a GIF or a PNG. Those are indexed color formats, where one of the index values can be made transparent. But in such a format, you could have 254 index values that all represented the same shade of green, and a 255th that becomes invisible. In this QuickDraw example, ''all'' green pixels are transparent. If you've worked with television equipment, this should be familiar as the ''chroma key'' concept frequently used in news and weather, where someone will stand in front of a green wall, and an effects box will replace all green pixels with video from another source.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are too many supported graphics mode values to list here, but some of the most useful are as follows:&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;srcCopy&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Copies source to destination. This is the normal behavior.&lt;br /&gt;
;&amp;lt;tt&amp;gt;transparent&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Punches out specified color and lets background show through.&lt;br /&gt;
;&amp;lt;tt&amp;gt;blend&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Mixes foreground and background colors.&lt;br /&gt;
;&amp;lt;tt&amp;gt;addPin&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Adds foreground and background colors, up to a maximum value.&lt;br /&gt;
;&amp;lt;tt&amp;gt;subPin&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Calculates the difference between sum and destination colors, to a minimum value.&lt;br /&gt;
;&amp;lt;tt&amp;gt;ditherCopy&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Replaces destination with a dither mix of source and destination.&lt;br /&gt;
&lt;br /&gt;
A complete list of values is provided in &amp;quot;Graphic Transfer Modes&amp;quot; on Apple's developer web site at ''http://developer.apple.com/''.&lt;/div&gt;</description>
			<pubDate>Thu, 06 Mar 2008 23:50:56 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:QuickTime_for_Java:_A_Developer%27s_Notebook/Working_with_QuickDraw</comments>		</item>
	</channel>
</rss>