//@author: Michael Shmulevich /* * @(#)JpegImagesToMovie.java 1.3 01/03/13 * * Copyright (c) 1999-2001 Sun Microsystems, Inc. All Rights Reserved. * * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, * modify and redistribute this software in source and binary code form, * provided that i) this copyright notice and license appear on all copies of * the software; and ii) Licensee does not utilize the software in a manner * which is disparaging to Sun. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * This software is not designed or intended for use in on-line control of * aircraft, air traffic, aircraft navigation or aircraft communications; or in * the design, construction, operation or maintenance of any nuclear * facility. Licensee represents and warrants that it will not use or * redistribute the Software for such purposes. */ import java.io.*; import java.util.*; import java.lang.*; import java.awt.Dimension; import java.awt.Image; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import javax.media.*; import javax.media.control.*; import javax.media.protocol.*; import javax.media.datasink.*; import javax.media.format.VideoFormat; /** * This program takes a list of JPEG image files and convert them into * a QuickTime movie. */ public class JpegImagesToMovie implements ControllerListener, DataSinkListener { public boolean doIt(int width, int height, int frameRate, Vector inFiles, MediaLocator outML) { ImageDataSource ids = new ImageDataSource(width, height, frameRate, inFiles); Processor p; try { System.out.println("- create processor for the image datasource ..."); p = Manager.createProcessor(ids); } catch (Exception e) { System.err.println("Yikes! Cannot create a processor from the data source."); return false; } p.addControllerListener(this); // Put the Processor into configured state so we can set // some processing options on the processor. p.configure(); if (!waitForState(p, p.Configured)) { System.err.println("Failed to configure the processor."); return false; } // Set the output content descriptor to QuickTime. p.setContentDescriptor(new ContentDescriptor(FileTypeDescriptor.QUICKTIME)); // Query for the processor for supported formats. // Then set it on the processor. TrackControl tcs[] = p.getTrackControls(); System.out.println("# track controls = " + tcs.length); for (int i=0; i= args.length) prUsage(); width = new Integer(args[i]).intValue(); } else if (args[i].equals("-h")) { i++; hFlag = true; if (i >= args.length) prUsage(); height = new Integer(args[i]).intValue(); } else if (args[i].equals("-f")) { i++; if (i >= args.length) prUsage(); float tempFrameRate = new Float(args[i]).floatValue(); // frameRate is number of frames displayed per second frameRate = (int) tempFrameRate; } else if (args[i].equals("-o")) { i++; if (i >= args.length) prUsage(); outputURL = ("file:" + args[i]); } else if (args[i].equals("-d")) { i++; if (i >= args.length) prUsage(); directory = args[i]; }else { prUsage(); } i++; } /* String osName = System.getProperty("os.name").toString(); int isWindows = osName.indexOf("Windows"); int isMac = osName.indexOf("Mac"); int isLinux = osName.indexOf("Linux"); int isUnix = osName.indexOf("Unix"); */ // outputURL = "file:" + System.getProperty("user.dir") + "out.mov"; File nf = new File(directory); //System.out.println("Working Directory is: "+nf.getParent()+nf.getName()); String[] files = nf.list(); Arrays.sort(files); /* for (int j = 0; j < files.length; j++) { System.out.println(files[j]); } */ for (int j = 0; j < files.length; j++){ if(files[j].contains(".jpg") || files[j].contains(".jpeg") || files[j].contains(".JPG") || files[j].contains(".JPEG") || files[j].contains(".png")) inputFiles.addElement(nf.getParent()+ System.getProperty("file.separator") + nf.getName()+ System.getProperty("file.separator") + files[j]); } BufferedImage img = null; try { img = ImageIO.read(new File((String) inputFiles.elementAt(0))); System.out.println(img); } catch (IOException e) { } if (img != null && wFlag == false && hFlag == false) { width = img.getWidth(); height = img.getHeight(); } /* For Testing Purposes Only: for (int j = 0; j <= 9840; j+=5) { inputFiles.addElement(String.format("C:\\images2\\xgc.fielde.%04d.h5.jpg",j)); } */ if (outputURL == null || inputFiles.size() == 0) prUsage(); // Check for output file extension. if (!outputURL.endsWith(".mov") && !outputURL.endsWith(".MOV")) { System.err.println("The output file extension should end with a .mov extension"); System.err.println("Appending .mov extension..."); outputURL += ".mov"; } if (width < 0 || height < 0) { System.err.println("Please specify the correct image size."); prUsage(); } // Check the frame rate. // if (frameRate < 1) // frameRate = 1; // Generate the output media locators. MediaLocator oml; if ((oml = createMediaLocator(outputURL)) == null) { System.err.println("Cannot build media locator from: " + outputURL); System.exit(0); } JpegImagesToMovie imageToMovie = new JpegImagesToMovie(); imageToMovie.doIt(width, height, frameRate, inputFiles, oml); System.exit(0); } static void prUsage() { System.out.println("\n***************WELCOME TO THE JpegImagesToMovie CONFIGURATION HELP MENU***************"); System.out.println("Usage: java JpegImagesToMovie -f -o -d "); System.out.println("\nWidth and Height are optional. They are automatically detected. \nYou may specify an overide by including -w -h parameters."); System.out.println("\n\nExample For Unix Users: java JpegImagesToMovie -f 10 -o /User/username/Desktop/out.mov -d /User/username/Desktop/images"); System.out.println("\n\nExample For Windows Users: java JpegImagesToMovie -f 10 -o C:\\out.mov -d C:\\images"); System.out.println("\nNote: If no output directory is specified, the output file will be placed in the user's current directory"); System.exit(-1); } /** * Create a media locator from the given string. */ static MediaLocator createMediaLocator(String url) { MediaLocator ml; if (url.indexOf(":") > 0 && (ml = new MediaLocator(url)) != null) return ml; if (url.startsWith(File.separator)) { if ((ml = new MediaLocator("file:" + url)) != null) return ml; } else { String file = "file:" + System.getProperty("user.dir") + File.separator + url; if ((ml = new MediaLocator(file)) != null) return ml; } return null; } /////////////////////////////////////////////// // // Inner classes. /////////////////////////////////////////////// /** * A DataSource to read from a list of JPEG image files and * turn that into a stream of JMF buffers. * The DataSource is not seekable or positionable. */ class ImageDataSource extends PullBufferDataSource { ImageSourceStream streams[]; ImageDataSource(int width, int height, int frameRate, Vector images) { streams = new ImageSourceStream[1]; streams[0] = new ImageSourceStream(width, height, frameRate, images); } public void setLocator(MediaLocator source) { } public MediaLocator getLocator() { return null; } /** * Content type is of RAW since we are sending buffers of video * frames without a container format. */ public String getContentType() { return ContentDescriptor.RAW; } public void connect() { } public void disconnect() { } public void start() { } public void stop() { } /** * Return the ImageSourceStreams. */ public PullBufferStream[] getStreams() { return streams; } /** * We could have derived the duration from the number of * frames and frame rate. But for the purpose of this program, * it's not necessary. */ public Time getDuration() { return DURATION_UNKNOWN; } public Object[] getControls() { return new Object[0]; } public Object getControl(String type) { return null; } } /** * The source stream to go along with ImageDataSource. */ class ImageSourceStream implements PullBufferStream { Vector images; int width, height; VideoFormat format; int nextImage = 0; // index of the next image to be read. boolean ended = false; public ImageSourceStream(int width, int height, int frameRate, Vector images) { this.width = width; this.height = height; this.images = images; format = new VideoFormat(VideoFormat.JPEG, new Dimension(width, height), Format.NOT_SPECIFIED, Format.byteArray, (float)frameRate); } /** * We should never need to block assuming data are read from files. */ public boolean willReadBlock() { return false; } /** * This is called from the Processor to read a frame worth * of video data. */ public void read(Buffer buf) throws IOException { // Check if we've finished all the frames. if (nextImage >= images.size()) { // We are done. Set EndOfMedia. // System.out.println("Done reading all images."); buf.setEOM(true); buf.setOffset(0); buf.setLength(0); ended = true; return; } String imageFile = (String)images.elementAt(nextImage); nextImage++; // System.out.println(" - ready to read image file: " + imageFile); if (imageFile.endsWith(".png")) { // convert to jpeg File file = new File(imageFile); // read the png BufferedImage inputImage = (BufferedImage) ImageIO.read(file); File jpgFile = new File(imageFile + ".jpg"); ImageIO.write(inputImage, "jpg", jpgFile); imageFile = new String(imageFile + ".jpg"); } // Open a random access file for the next image. RandomAccessFile raFile; // System.out.println(" - reading image file: " + imageFile); raFile = new RandomAccessFile(imageFile, "r"); byte data[] = null; // Check the input buffer type & size. if (buf.getData() instanceof byte[]) data = (byte[])buf.getData(); // Check to see the given buffer is big enough for the frame. if (data == null || data.length < raFile.length()) { data = new byte[(int)raFile.length()]; buf.setData(data); } // Read the entire JPEG image from the file. raFile.readFully(data, 0, (int)raFile.length()); // System.out.println(" read " + raFile.length() + " bytes."); buf.setOffset(0); buf.setLength((int)raFile.length()); buf.setFormat(format); buf.setFlags(buf.getFlags() | buf.FLAG_KEY_FRAME); // Close the random access file. raFile.close(); } /** * Return the format of each video frame. That will be JPEG. */ public Format getFormat() { return format; } public ContentDescriptor getContentDescriptor() { return new ContentDescriptor(ContentDescriptor.RAW); } public long getContentLength() { return 0; } public boolean endOfStream() { return ended; } public Object[] getControls() { return new Object[0]; } public Object getControl(String type) { return null; } } } /* if(files[j].contains(".jpg") && (isLinux != -1 || isMac != -1 || isUnix != -1)) inputFiles.addElement(nf.getParent()+ "/" + nf.getName()+ "/" + files[j]); if(files[j].contains(".png")){ String filename=null; BufferedImage image = null; File input = new File(nf.getParent()+ System.getProperty("file.separator") + nf.getName()+ System.getProperty("file.separator") + files[j]); try { image = ImageIO.read(input); } catch (IOException e) { e.printStackTrace(); } int dot = files[j].lastIndexOf('.'); if(dot != -1){ filename = files[j].substring(0,dot); filename+= ".jpg"; } //if(filename != null) File output = new File(nf.getParent()+ System.getProperty("file.separator") + nf.getName()+ System.getProperty("file.separator") + filename); try { ImageIO.write(image, "jpg", output); } catch (IOException e) { e.printStackTrace(); } inputFiles.addElement(output.toString()); } */