Women in Technology

Hear us Roar



Article:
  The Return of the Blue Q
Subject:   Having trouble with frame grabbing (code from another article)
Date:   2004-07-21 09:02:10
From:   johnmangum

I was trying out the code grabbing a frame from a movie in your article here.


http://www.onjava.com/pub/a/onjava/2002/12/23/jmf.html?page=2


But I'm having trouble getting a good jpeg file from a movie. Here's the code:



QTSession.open();
QTFile qtFile = new QTFile("/Users/josh/kelley20.mp4");


OpenMovieFile movieFile = OpenMovieFile.asRead(qtFile);
Movie movie = Movie.fromFile(movieFile);
int j = 0;
int step = (movie.getDuration() - movie.getTime())/5;
for (int i = movie.getTime(); i < movie.getDuration(); i += step) {
j++;
Pict pict = movie.getPict(i); // frame number
File f = new File("/Users/josh/quicktime/test" + j +".jpeg");

pict.writeToFile(f);
}
QTSession.close();
System.exit(0);


It almost works. There is a file saved and I can open it in safari and it's the right picture. Unfortunately it won't open in camino ("this jpeg contains errors") or preview. It's not really a jpeg though. Graphics Converter says its file format is "QuickTime Importer (QuickDraw)".


Any idea how i can convert this into a jpeg? I've tried using GraphicsImporter,on the file like this:



GraphicsImporter gi = new GraphicsImporter(qtFile); // get a cantFindHandler error here
GraphicsImporterDrawer myDrawer = new GraphicsImporterDrawer
(gi);
QTImageProducer qtProducer = new QTImageProducer (myDrawer,
size);
Image image = Toolkit.getDefaultToolkit().createImage(qtProducer);


but I get the "Unsupported on Mac OS X and Java 1.4 and higher" error on the GraphicsImporterDrawer line. I'm using 10.2, could that be a problem? (I think i've updated quicktime java properly).


Could i use ibm's toolkit for this?


Thanks for your help and great articles, J.

Full Threads Newest First

Showing messages 1 through 5 of 5.

  • Chris Adamson photo Having trouble with frame grabbing (code from another article)
    2004-07-22 10:27:30  Chris Adamson | O'Reilly AuthorO'Reilly Blogger [View]

    This is coming in a soon-to-be-announced QTJ book from O'Reilly (pause for effect of thundering applause), which I'm just now able to talk about. I'm trying to get the example code posted on an open-source site (probably java.net) ASAP.

    Anyways, I did the QuickDraw chapter a few weeks ago. What you've done is shockingly close to something in the book.

    Two catches:

    • you don't need to write the Picts to disk. Copy a Pict's bytes to a buffer that's 512 bytes larger, so you have a 512-byte header pad. Point the GraphicsImporter to that memory with setDataReference().
    • there are two GraphicsImporterDrawers. You seem to be picking up the deprecated one from quicktime.app.image (all of which is gone). Check your imports to make sure you're getting the new one from quicktime.app.view.

    --Chris (invalidname)


    • Having trouble with frame grabbing (code from another article)
      2004-09-13 19:16:07  ktown [View]

      Has this code now been made available somewhere? Is the new QTJ book announced?
      • Chris Adamson photo Having trouble with frame grabbing (code from another article)
        2004-09-25 11:03:30  Chris Adamson | O'Reilly AuthorO'Reilly Blogger [View]

        The book is coming in December - working through tech review now. The grab-a-movie-frame trick with the GraphicsImporter and the 512-byte pseudo-header is spelled out with code (from the book) in a message I posted to the quicktime-java mailing list:

        http://lists.apple.com/archives/quicktime-java/2004/Jul/msg00032.html

        -Chris
        • Having trouble with frame grabbing (code from another article)
          2005-01-23 13:26:16  johnmangum [View]

          By the way I figured out a fairly clean way to to this. Excuse the Pr.tln functions, just my way of doing System.out.println.


          static public ArrayList makeFrames(String movieFilename, int numFrames, String prepend,
          String directory) {
          ArrayList resultFiles = new ArrayList();

          try {
          QTSession.open();
          QTFile qtFile = new QTFile(movieFilename);

          OpenMovieFile movieFile = OpenMovieFile.asRead(qtFile);
          Movie movie = Movie.fromFile(movieFile);
          int duration = movie.getDuration() - movie.getTime();
          int j = 0;
          int step = (duration + numFrames*2)/numFrames;
          step = (int) (step * .95);
          Pict pict = null;
          QTFile f = null;
          for (int i = movie.getTime() + (int)(duration * .05); i < movie.getDuration(); i += step) {
          j++;

          pict = movie.getPict(i); // frame number
          Pr.tln("size: " +pict.getSize() +", i: " +i);
          Pr.tln(pict.getPictFrame());
          String fullFileName = directory +File.separator+ prepend +j +".jpeg";

          f = new QTFile(fullFileName);
          resultFiles.add(f.getName());
          GraphicsExporter graphicsExporter = new GraphicsExporter(StdQTConstants.kQTFileTypeJPEG);
          graphicsExporter.setCompressionQuality(StdQTConstants.codecNormalQuality);
          graphicsExporter.setOutputFile(f);
          graphicsExporter.setInputPicture(pict);
          graphicsExporter.doExport();

          }
          QTSession.close();

          } catch (Exception e) {
          throw (new RuntimeException(e));
          } finally {
          QTSession.close();
          }

          return resultFiles;
          }

        • Having trouble with frame grabbing (code from another article)
          2005-01-23 13:27:32  johnmangum [View]

          By the way I figured out a fairly clean way to to this. Excuse the Pr.tln functions, just my way of doing System.out.println.


          static public ArrayList makeFrames(String movieFilename, int numFrames, String prepend,
          String directory) {
          ArrayList resultFiles = new ArrayList();

          try {
          QTSession.open();
          QTFile qtFile = new QTFile(movieFilename);

          OpenMovieFile movieFile = OpenMovieFile.asRead(qtFile);
          Movie movie = Movie.fromFile(movieFile);
          int duration = movie.getDuration() - movie.getTime();
          int j = 0;
          int step = (duration + numFrames*2)/numFrames;
          step = (int) (step * .95);
          Pict pict = null;
          QTFile f = null;
          for (int i = movie.getTime() + (int)(duration * .05); i < movie.getDuration(); i += step) {
          j++;

          pict = movie.getPict(i); // frame number
          Pr.tln("size: " +pict.getSize() +", i: " +i);
          Pr.tln(pict.getPictFrame());
          String fullFileName = directory +File.separator+ prepend +j +".jpeg";

          f = new QTFile(fullFileName);
          resultFiles.add(f.getName());
          GraphicsExporter graphicsExporter = new GraphicsExporter(StdQTConstants.kQTFileTypeJPEG);
          graphicsExporter.setCompressionQuality(StdQTConstants.codecNormalQuality);
          graphicsExporter.setOutputFile(f);
          graphicsExporter.setInputPicture(pict);
          graphicsExporter.doExport();

          }
          QTSession.close();

          } catch (Exception e) {
          throw (new RuntimeException(e));
          } finally {
          QTSession.close();
          }

          return resultFiles;
          }