Java/2D Graphics GUI/JMF

Материал из Java эксперт
Перейти к: навигация, поиск

A motion detection algoritm for use with the Java Media Framework API (JMF).

  

/**
 * A motion detection algoritm for use with the Java Media Framework API (JMF).
 * The main idea of the algorithm is to compare the pixelcolours of two successive frames in an incoming videostream.
 * To prevent noise to be mistaken for motion each frame is divided into many small squares for which only the mean colour is used for compairson.
 * @version 2002-09-26
 * @author Mattias Hedlund, mathed-8.
 * @author Fredrik Jonsson, frejon-9.
 * @author David Åberg, davabe-9 all students at Luleå University of Technology.
 */
import javax.media.*;
import javax.media.format.*;
import java.awt.*;
import java.io.IOException;
public class MotionDetectionEffect implements Effect {
    /**
     * The initial square side.
     */
    private final static int INITIAL_SQUARE_SIZE = 5;
    public final static Format[] supportedFormat = new Format[] { // 
    new RGBFormat(null, //
            Format.NOT_SPECIFIED, // 
            Format.byteArray, //
            Format.NOT_SPECIFIED, //
            24, //
            3, 2, 1, //
            3, Format.NOT_SPECIFIED, //
            Format.TRUE, //
            Format.NOT_SPECIFIED) //
    };
    private Format inputFormat;
    private Format outputFormat;
    private Format[] inputFormats;
    private Format[] outputFormats;
    private int[] bwPixels;
    private byte[] bwData;
    /**
     * Visual mode is set.
     */
    private boolean visualize = true;
    /**
     * Server mode is set.
     */
    private boolean serverActive = true;
    /**
     * Update requested is set.
     */
    private boolean updateRequested;
    private int avg_ref_intensity;
    private int avg_img_intensity;
    /**
     * The RGBFormat of the inbuffer.
     */
    private RGBFormat vfIn = null;
    /**
     * Four different thresholds. Set initial values here.
     */
    private int[] threshs = { 20, 30, 40, 50 };
    private int det_thresh = threshs[1];
    /**
     *  The corresponding colours to the four different thresholds.
     */
    private int[] colors = { 0x00FF0000, 0x00FF9900, 0x00FFFF00, 0x00FFFFFF };
    /**
     *  The mean values of all squares in an image.
     */
    private int[] newImageSquares = null;
    /**
     *  The mean values of all squares in an image.
     */
    private int[] oldImageSquares = null;
    /**
     *  The difference of all the mean values of all squares in an image.
     */
    private int[] changedSquares = null;
    /**
     * The number of squares fitted in the image.
     */
    private int numberOfSquaresWide;
    /**
     * The number of squares fitted in the image.
     */
    private int numberOfSquaresHigh;
    /**
     * The number of squares fitted in the image.
     */
    private int numberOfSquares;
    /**
     * The square side, in pixels.
     */
    private int sqSide = INITIAL_SQUARE_SIZE;
    /**
     * The square area, in pixels.
     */
    private int sqArea = 0;
    /**
     * The amount of pixels left when all normal sized squares have been removed.
     */
    private int sqWidthLeftover = 0;
    /**
     * The amount of pixels left when all normal sized squares have been removed.
     */
    private int sqHeightLeftover = 0;
    /**
     * Optional, less processing is needed if some pixels are left out during some of the calculations.
     */
    private int pixelSpace = 0;
    /**
     * Image property.
     */
    private int imageWidth = 0;
    /**
     * Image property.
     */
    private int imageHeight = 0;
    /**
     * Image property.
     */
    private int imageArea = 0;
    /**
     * Initialize the effect plugin.
     */
    public MotionDetectionEffect() {
        inputFormats = new Format[] { new RGBFormat(null, Format.NOT_SPECIFIED, Format.byteArray, Format.NOT_SPECIFIED, 24, 3, 2, 1, 3, Format.NOT_SPECIFIED, Format.TRUE, Format.NOT_SPECIFIED) };
        outputFormats = new Format[] { new RGBFormat(null, Format.NOT_SPECIFIED, Format.byteArray, Format.NOT_SPECIFIED, 24, 3, 2, 1, 3, Format.NOT_SPECIFIED, Format.TRUE, Format.NOT_SPECIFIED) };
    }
    /**
     * Get the inputformats that we support.
     * @return  All supported Formats.
     */
    public Format[] getSupportedInputFormats() {
        return inputFormats;
    }
    /**
     * Get the outputformats that we support.
     * @param input the current inputformat.
     * @return  All supported Formats.
     */
    public Format[] getSupportedOutputFormats(Format input) {
        if (input == null) {
            return outputFormats;
        }
        if (matches(input, inputFormats) != null) {
            return new Format[] { outputFormats[0].intersects(input) };
        } else {
            return new Format[0];
        }
    }
    /**
     * Set the input format.
     * 
     */
    public Format setInputFormat(Format input) {
        inputFormat = input;
        return input;
    }
    /**
     * Set our output format.
     *
     */
    public Format setOutputFormat(Format output) {
        if (output == null || matches(output, outputFormats) == null)
            return null;
        RGBFormat incoming = (RGBFormat) output;
        Dimension size = incoming.getSize();
        int maxDataLength = incoming.getMaxDataLength();
        int lineStride = incoming.getLineStride();
        float frameRate = incoming.getFrameRate();
        int flipped = incoming.getFlipped();
        int endian = incoming.getEndian();
        if (size == null)
            return null;
        if (maxDataLength < size.width * size.height * 3)
            maxDataLength = size.width * size.height * 3;
        if (lineStride < size.width * 3)
            lineStride = size.width * 3;
        if (flipped != Format.FALSE)
            flipped = Format.FALSE;
        outputFormat = outputFormats[0].intersects(new RGBFormat(size, maxDataLength, null, frameRate, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, lineStride, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED));
        return outputFormat;
    }
    /**
     * Process the buffer. This is where motion is analysed and optionally visualized.
     *
     */
    public synchronized int process(Buffer inBuffer, Buffer outBuffer) {
        int outputDataLength = ((VideoFormat) outputFormat).getMaxDataLength();
        validateByteArraySize(outBuffer, outputDataLength);
        outBuffer.setLength(outputDataLength);
        outBuffer.setFormat(outputFormat);
        outBuffer.setFlags(inBuffer.getFlags());
        byte[] inData = (byte[]) inBuffer.getData();
        byte[] outData = (byte[]) outBuffer.getData();
        int[] sqAvg = null;
        int[] refsqAvg = null;
        vfIn = (RGBFormat) inBuffer.getFormat();
        Dimension sizeIn = vfIn.getSize();
        int pixStrideIn = vfIn.getPixelStride();
        int lineStrideIn = vfIn.getLineStride();
        imageWidth = (vfIn.getLineStride()) / 3; //Divide by 3 since each pixel has 3 colours.
        imageHeight = ((vfIn.getMaxDataLength()) / 3) / imageWidth;
        imageArea = imageWidth * imageHeight;
        int r, g, b = 0; //Red, green and blue values.
        if (oldImageSquares == null) { //For the first frame.
            changeSqSize(INITIAL_SQUARE_SIZE);
            updateRequested = true;
        }
        //Copy all data from the inbuffer to the outbuffer. The purpose is to display the video input on the screen.
        System.arraycopy(inData, 0, outData, 0, outData.length);
        // Simplify the image to black and white, image information shrinks to one third of the original amount. Less processing needed.
        bwPixels = new int[outputDataLength / 3];
        for (int ip = 0; ip < outputDataLength; ip += 3) {
            int bw = 0;
            r = (int) inData[ip] & 0xFF;
            g = (int) inData[ip + 1] & 0xFF;
            b = (int) inData[ip + 2] & 0xFF;
            bw = (int) ((r + b + g) / (double) 3);
            bwPixels[ip / 3] = bw; //Now containing a black and white image. 
        }
        if (updateRequested) {
            updateRequested = false;
            updateSquares();
            return BUFFER_PROCESSED_OK;
        } else {
            updateSquares();
            oldNewChange();
            int c = 0;
            for (int i = 0; i < changedSquares.length; i++) {
                if (changedSquares[i] > det_thresh) {
                    c++;
                }
            }
            if (c > 10 && serverActive) {
                //    try{
                System.out.println("Motion detected (motion at " + c + "areas");
                //      multicast.send("Motion detected");  - Disabled
                //    } catch(IOException e){}
            }
            // If chosen, the detected motion is presented on top of the video input, thus covering the edges of the moving object. 
            if (visualize) {
                for (int i = 1; i <= numberOfSquares; i++) { // For all blobs
                    if ((changedSquares[i - 1] > threshs[0])) { // Critical threshold, if less, then no motion is said to have occured.
                        if (((i % numberOfSquaresWide) != 0) && (numberOfSquares - i) > numberOfSquaresWide) {//Normal square, the other cases is not presented!
                            int begin = ((((i % numberOfSquaresWide) - 1) * sqSide) + ((i / numberOfSquaresWide) * imageWidth * sqSide)) * 3; //Calculate start of square.
                            if (changedSquares[i - 1] > threshs[3]) { //Very strong motion.
                                b = (byte) (colors[3] & 0xFF);
                                g = (byte) ((colors[3] >> 8) & 0xFF);
                                r = (byte) ((colors[3] >> 16) & 0xFF);
                            } else if (changedSquares[i - 1] > threshs[2]) { //Strong motion.
                                b = (byte) (colors[2] & 0xFF);
                                g = (byte) ((colors[2] >> 8) & 0xFF);
                                r = (byte) ((colors[2] >> 16) & 0xFF);
                            } else if (changedSquares[i - 1] > threshs[1]) { //Weak motion.
                                b = (byte) (colors[1] & 0xFF);
                                g = (byte) ((colors[1] >> 8) & 0xFF);
                                r = (byte) ((colors[1] >> 16) & 0xFF);
                            } else { //The Weakest motion detected.
                                b = (byte) (colors[0] & 0xFF);
                                g = (byte) ((colors[0] >> 8) & 0xFF);
                                r = (byte) ((colors[0] >> 16) & 0xFF);
                            }
                            for (int k = begin; k < (begin + (sqSide * imageWidth * 3)); k = k + (imageWidth * 3)) { //Ev <=
                                for (int j = k; j < (k + (sqSide * 3)); j = j + 3) {
                                    try {
                                        outData[j] = (byte) b;
                                        outData[j + 1] = (byte) g;
                                        outData[j + 2] = (byte) r;
                                    } catch (ArrayIndexOutOfBoundsException e) {
                                        System.out.println("Nullpointer: j = " + j + ". Outdata.length = " + outData.length);
                                        System.exit(1);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return BUFFER_PROCESSED_OK;
    }
    // Methods for interface PlugIn
    public String getName() {
        return "Motion Detection Codec";
    }
    public void open() {
    }
    public void close() {
    }
    public void reset() {
    }
    // Methods for interface javax.media.Controls
    public Object getControl(String controlType) {
        System.out.println(controlType);
        return null;
    }
    public Object[] getControls() {
        return null;
    }
    // Utility methods.
    public Format matches(Format in, Format outs[]) {
        for (int i = 0; i < outs.length; i++) {
            if (in.matches(outs[i]))
                return outs[i];
        }
        return null;
    }
    // Credit : example at www.java.sun.ru
    byte[] validateByteArraySize(Buffer buffer, int newSize) {
        Object objectArray = buffer.getData();
        byte[] typedArray;
        if (objectArray instanceof byte[]) { // Has correct type and is not null
            typedArray = (byte[]) objectArray;
            if (typedArray.length >= newSize) { // Has sufficient capacity
                return typedArray;
            }
            byte[] tempArray = new byte[newSize]; // Reallocate array
            System.arraycopy(typedArray, 0, tempArray, 0, typedArray.length);
            typedArray = tempArray;
        } else {
            typedArray = new byte[newSize];
        }
        buffer.setData(typedArray);
        return typedArray;
    }
    /**
     * Sets the current pixelspace, default is zero.
     * This is mainly for use where limited processing capacity are availible. Some pixels are left out in the calculations.
     * @param newSpace the space between two successive pixels.
     */
    private void setPixelSpace(int newSpace) {
        pixelSpace = newSpace;
    }
    /**
     * Changes the size of the square shaped area that divides the detection area into many small parts.
     * @param newSide the side of the square, in pixels.
     */
    private void changeSqSize(int newSide) {
        sqSide = newSide;
        sqArea = newSide * newSide;
        int wid = (imageWidth / sqSide); //The number of squares wide.
        int hei = (imageHeight / sqSide); //The number of squares high.
        sqWidthLeftover = imageWidth % sqSide;
        sqHeightLeftover = imageHeight % sqSide;
        if (sqWidthLeftover > 0) {
            wid++;
        }
        if (sqHeightLeftover > 0) {
            hei++;
        }
        numberOfSquaresWide = wid;
        numberOfSquaresHigh = hei;
        numberOfSquares = wid * hei;
        newImageSquares = new int[numberOfSquares];
        oldImageSquares = new int[numberOfSquares];
        changedSquares = new int[numberOfSquares];
    }
    /**
     * Calculates the average colour in each square thus indirect eliminate noise.
     * @param startX the starting position of this square, in pixels, left edge.
     * @param startY the starting position of this square, in pixels, bottom edge.
     * @param sqWidth the width of this square, in pixels.
     * @param sqHeight the height of this square, in pixels.
     * @return The average greyscale value for this square.
     */
    private int averageInSquare(int startX, int startY, int sqWidth, int sqHeight) {
        int average = 0;
        for (int i = 0; i < sqHeight; i = i + 1 + pixelSpace) {// For all pixels
            for (int j = 0; j < sqWidth; j = j + 1 + pixelSpace) {
                average += bwPixels[(((startY + i) * imageWidth) + (startX + j))]; //Sum all the pixel values.
            }
        }
        average = average / (sqWidth * sqHeight); //Divide by the number of pixels to get the average value.
        return average;
    }
    /**
     * Backup the most recent frame examined. For the new frame, calculate the average greyscale value for all squares.
     */
    private void updateSquares() {
        System.arraycopy(newImageSquares, 0, oldImageSquares, 0, newImageSquares.length);
        int sqCount = 0; //Keep track of the current square
        for (int j = 0; j < (imageHeight); j = j + sqSide) { //For all squares
            for (int i = 0; i < (imageWidth); i = i + sqSide) {
                if (i <= (imageWidth - sqSide) && j <= (imageHeight - sqSide)) {
                    newImageSquares[sqCount] = averageInSquare(i, j, sqSide, sqSide); //No edge!
                } else if (i > (imageWidth - sqSide) && j <= (imageHeight - sqSide)) {
                    newImageSquares[sqCount] = averageInSquare(i, j, sqWidthLeftover, sqSide); //Right edge!
                } else if (i <= (imageWidth - sqSide) && j > (imageHeight - sqSide)) {
                    newImageSquares[sqCount] = averageInSquare(i, j, sqSide, sqHeightLeftover); //Bottom edge!
                } else if (i > (imageWidth - sqSide) && j > (imageHeight - sqSide)) {
                    newImageSquares[sqCount] = averageInSquare(i, j, sqWidthLeftover, sqHeightLeftover); //Bottom right edge!
                }
                sqCount++;
            }
        }
    }
    /**
     * Calculate the difference per square between currently stored frames. 
     */
    private void oldNewChange() {
        for (int i = 0; i <= (numberOfSquares - 1); i++) { //For all squares
            int difference = Math.abs((newImageSquares[i]) - (oldImageSquares[i])); //Compare each square with the corresponding square in the previous frame.
            changedSquares[i] = difference; //Save the difference.
        }
    }
    public synchronized void updateModel(boolean visualize, boolean serverActive, boolean simplified, int[] threshs, int[] colors, int sqSide, int det_thresh) {
        this.visualize = visualize;
        this.serverActive = serverActive;
        if (sqSide != this.sqSide)
            changeSqSize(sqSide);
        if (!simplified) {
            System.out.println((colors == null) + " " + (this.colors == null));
            System.arraycopy(colors, 0, this.colors, 0, colors.length);
            System.arraycopy(threshs, 0, this.threshs, 0, colors.length);
            this.det_thresh = det_thresh;
            System.out.println("New det_threhsh: " + this.det_thresh);
        }
        updateRequested = true;
    }
    /**
     *Check if the visualize variable is set.
     *@returns the current value.
     */
    public boolean isVisual() {
        return visualize;
    }
    /**
     *Get the current threshold values in a vector.
     *@returns the current values.
     */
    public int[] getThreshholds() {
        return threshs;
    }
    /**
     *Check if the server is active.
     *@returns the current value.
     */
    public boolean isServerActive() {
        return serverActive;
    }
    public int[] getColors() {
        return colors;
    }
    /**
     *Get the current square side.
     *@returns the current value.
     */
    public int getSqSide() {
        return sqSide;
    }
}



javax.media

    
//-----------------------------------------------------------------------//
//                                                                       //
//                           T e s t I m a g e 3                         //
//                                                                       //
//  Copyright (C) Herve Bitteur 2000-2007. All rights reserved.          //
//  This software is released under the terms of the GNU General Public  //
//  License. Please contact the author at herve.bitteur@laposte.net      //
//  to report bugs & suggestions.                                        //
//-----------------------------------------------------------------------//
package omr.jai;
import omr.jai.ImageInfo;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.ParameterBlock;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.Arrays;
import javax.media.jai.InterpolationNearest;
import javax.media.jai.InterpolationBilinear;
public class TestImage3
    extends JPanel
{
    //RenderedImage image;
    PlanarImage image;
    // Affine tranform
    final float ratio = 4f;
    AffineTransform scaleXform = AffineTransform.getScaleInstance(ratio, ratio);
    private static char WHITE = "-";    // And transparent
    private static char[] charTable = new char[]
    {
        "#",  // 0 Black
        "$",  // 1
        "*",  // 2
        "0",  // 3
        "o",  // 4
        "+",  // 5
        ".",  // 6
        WHITE // 7
    };
    //------------//
    // TestImage3 //
    //------------//
    public TestImage3()
    {
        JFrame frame = new JFrame(getClass().getName());
        Container pane = frame.getContentPane();
        pane.setLayout(new BorderLayout());
        pane.add(this);
        image = decodeImage(new String[] {
                "#-###############",
                "-----------------",
                "#################",
                "-----------------",
                "#################",
                "-----------------",
                "#################",
                "-----------------",
                "#################",
                "-----------------",
                "#################",
                "-----------------",
                "-----------------",
                "-----------------",
                "---####----------",
                "-------##--------",
                "---------####----",
                "-------------#---",
                "-------------#---",
                "-----------------",
                "--#############--",
                "--#############--",
                "--#############--",
                "--#############--",
                "--#############--",
                "--#############--",
                "--#############--",
                "--#############--",
                "--#############--",
                "--#############--",
                "--#############--",
                "-----------------",
                "-----------------",
                "---####----------",
                "-------##--------",
                "---------####----",
                "-------------#---",
                "-------------#---",
                "-----------------",
                "--#############--",
                "--#############--",
                "-----------------",
                "-----------------"
        });
        //        checkImageFormat();
        ImageInfo.print(image);
        // Scaling
        final float scale = 1f;
        ParameterBlock pb = new ParameterBlock()
            .addSource(image)
            .add(scale)
            .add(scale)
            .add(0f)
            .add(0f)
            .add(new InterpolationNearest());
        image = JAI.create("scale", pb);
        dumpPixels(0, 0, 5, 7);
        if (false) {
            System.out.println("\nBand Selection");
            image = JAI.create("bandselect",image,new int[] {0, 1, 2});
            ImageInfo.print(image);
            dumpPixels(0, 0, 5, 7);
        }
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(100, 100);
        frame.pack();
        frame.setSize(100, 250);
        frame.setVisible(true);
    }
    private void dumpPixels (int x0,
                             int y0,
                             int w,
                             int h)
    {
        Raster raster = image.getData();
        int[] pixel = null;
        System.out.print("pixels=");
        for (int y = y0; y < y0+h; y++) {
            System.out.println();
            for (int x = x0; x <= x0+w; x++) {
                pixel = raster.getPixel(x, y, pixel);
                System.out.print(" [");
                for (int i = 0; i < pixel.length; i++) {
                    System.out.print(String.format("%3x", pixel[i]));
                }
                System.out.print("]");
            }
        }
        System.out.println();
    }

    //------//
    // main //
    //------//
    public static void main(String... args)
    {
        new TestImage3();
    }
    //----------------//
    // paintComponent //
    //----------------//
    public void paintComponent(Graphics g)
    {
        // For background
        super.paintComponent(g);
        // Meant for visual check
        if (image != null) {
            Graphics2D g2 = (Graphics2D) g;
            g2.drawRenderedImage (image, scaleXform);
            //g2.drawImage (image, 1, 1, this);
        }
    }
    //-------------//
    // decodeImage //
    //-------------//
    public static PlanarImage decodeImage (String[] rows)
    {
        // Create the DataBuffer to hold the pixel samples
        final int width = rows[0].length();
        final int height = rows.length;
        // Create Raster
        Raster raster;
        if (true) {
            raster = Raster.createPackedRaster
            (DataBuffer.TYPE_INT, width, height,
             new int[] {0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000},// bandMasks RGBA
             null);
        } else {
            raster = Raster.createInterleavedRaster
                (DataBuffer.TYPE_BYTE, width, height,
                 4,// num of bands
                 null);
        }
        // Populate the data buffer
        DataBuffer dataBuffer = raster.getDataBuffer();
        int index = 0;
        for (String row : rows) {
            for (int x = 0; x < width; x++) {
                int argb = toARGB(row.charAt(x));
                dataBuffer.setElem(index, argb);
                index++;
            }
        }
        // Dump
//         final int size = width * height;
//         System.out.println("DataBuffer :");
//         for (int i = 0; i < size; i++) {
//             if (i % width == 0) {
//                 System.out.println();
//             }
//             System.out.print(String.format("%8x ", dataBuffer.getElem(i)));
//         }
//         System.out.println();
        // Create the image
        BufferedImage bufferedImage = new BufferedImage
                (width, height, BufferedImage.TYPE_INT_ARGB);
        bufferedImage.setData(raster);
        // Dump
//         System.out.println("BufferedImage :");
//         for (int y = 0; y < height; y++) {
//             System.out.println();
//             for (int x = 0; x < width; x++) {
//                 System.out.print(String.format("%8x ", bufferedImage.getRGB(x, y)));
//             }
//         }
//         System.out.println();
        return PlanarImage.wrapRenderedImage(bufferedImage);
    }
    //--------//
    // toARGB //
    //--------//
    /**
     * Compute the ARGB pixel that corresponds to the given char
     *
     * @param c the char
     * @return the corresponding pixel value (ARGB format)
     */
    private static int toARGB (char c)
    {
        // Check the char
        if (c == WHITE) {
            return 0x00ffffff;      // Totally transparent / white
        } else {
            for (int i = charTable.length -1; i >= 0; i--) {
                if (charTable[i] == c) {
                    int level = 3 + i * 36; // Range 3 .. 255 (not too bad)
                    return
                        255   << 24 |      // Alpha (opaque)
                        level << 16 |      // R
                        level <<  8 |      // G
                        level;             // B
                }
            }
        }
        return 0x00ffffff;      // Totally transparent / white
    }
    //------------------//
    // checkImageFormat //
    //------------------//
    /**
     * Check if the image format (and especially its color model) is
     * properly handled by Audiveris.
     *
     * @throws ImageFormatException is the format is not supported
     */
    private void checkImageFormat()
    {
        // Check nb of bands
        int numBands = image.getSampleModel().getNumBands();
        if (numBands != 1) {
            if (numBands == 3) {
                image = colorToGray(image);
            } else {
                throw new RuntimeException
                    ("Unsupported sample model" +
                     " numBands=" + numBands);
            }
        }
        // Check pixel size
        ColorModel colorModel = image.getColorModel();
        int pixelSize = colorModel.getPixelSize();
        if (pixelSize != 8) {
            System.out.println("pixelSize=" + pixelSize +
                    " colorModel=" + colorModel);
            image = grayToGray256(image);
        }
    }
    //--------//
    // invert //
    //--------//
    private static PlanarImage invert (PlanarImage image)
    {
        return JAI.create("Invert",
                          new ParameterBlock()
                          .addSource(image)
                          .add(null)
                          .add(null)
                          .add(null)
                          .add(null)
                          .add(null),
                          null);
    }
    //-------------//
    // colorToGray //
    //-------------//
    private static PlanarImage colorToGray (PlanarImage image)
    {
        System.out.println("Converting color image to gray ...");
        double[][] matrix = { {0.114d, 0.587d, 0.299d, 0.0d} };
        return JAI.create("bandcombine",
                          new ParameterBlock()
                          .addSource(image)
                          .add(matrix),
                          null);
    }
    //---------------//
    // grayToGray256 //
    //---------------//
    private static PlanarImage grayToGray256 (PlanarImage image)
    {
        System.out.println("Converting gray image to gray-256 ...");
        ColorSpace colorSpace = ColorSpace.getInstance
            (java.awt.color.ColorSpace.CS_GRAY);
//        int[] bits = new int[]{8};
//        int opaque = Transparency.OPAQUE;
//        int dataType = DataBuffer.TYPE_BYTE;
//        ColorModel colorModel = new ComponentColorModel
//            (colorSpace, bits, false, false, opaque, dataType);
        return JAI.create("colorConvert", image, colorSpace, null);
    }
}
//-----------------------------------------------------------------------//
////
//I m a g e I n f o                           //
////
//Copyright (C) Herve Bitteur 2000-2007. All rights reserved.          //
//This software is released under the terms of the GNU General Public  //
//License. Please contact the author at herve.bitteur@laposte.net      //
//to report bugs & suggestions.                                        //
//-----------------------------------------------------------------------//

import java.awt.Transparency;
import java.awt.image.*;
import java.io.File;
import javax.media.jai.*;
public class ImageInfo
{
public static void main(String[] args)
{
// Open the image (using the name passed as a command line parameter)
PlanarImage pi = JAI.create("fileload", args[0]);
// Get the image file size (non-JAI related).
File image = new File(args[0]);
System.out.println("Image file size: "+image.length()+" bytes.");
print(pi);
}
public static void print (PlanarImage pi)
{
// Show the image dimensions and coordinates.
System.out.print("Image Dimensions: ");
System.out.print(pi.getWidth()+"x"+pi.getHeight()+" pixels");
// Remember getMaxX and getMaxY return the coordinate of the next point!
System.out.println(" (from "+pi.getMinX()+","+pi.getMinY()+" to " +
(pi.getMaxX()-1)+","+(pi.getMaxY()-1)+")");
if ((pi.getNumXTiles() != 1)||(pi.getNumYTiles() != 1)) { // Is it tiled?
// Tiles number, dimensions and coordinates.
System.out.print("Tiles: ");
System.out.print(pi.getTileWidth()+"x"+pi.getTileHeight()+" pixels"+
" ("+pi.getNumXTiles()+"x"+pi.getNumYTiles()+" tiles)");
System.out.print(" (from "+pi.getMinTileX()+","+pi.getMinTileY()+
" to "+pi.getMaxTileX()+","+pi.getMaxTileY()+")");
System.out.println(" offset: "+pi.getTileGridXOffset()+","+
pi.getTileGridXOffset());
}
// Display info about the SampleModel of the image.
SampleModel sm = pi.getSampleModel();
System.out.println("Number of bands: "+sm.getNumBands());
System.out.print("Data type: ");
switch(sm.getDataType()) {
case DataBuffer.TYPE_BYTE: System.out.println("byte"); break;
case DataBuffer.TYPE_SHORT: System.out.println("short"); break;
case DataBuffer.TYPE_USHORT: System.out.println("ushort"); break;
case DataBuffer.TYPE_INT: System.out.println("int"); break;
case DataBuffer.TYPE_FLOAT: System.out.println("float"); break;
case DataBuffer.TYPE_DOUBLE: System.out.println("double"); break;
case DataBuffer.TYPE_UNDEFINED:System.out.println("undefined"); break;
}
// Display info about the ColorModel of the image.
ColorModel cm = pi.getColorModel();
if (cm != null)
{
System.out.println("Number of color components: "+
cm.getNumComponents());
System.out.println("Bits per pixel: "+cm.getPixelSize());
System.out.print("Image Transparency: ");
switch(cm.getTransparency()) {
case Transparency.OPAQUE: System.out.println("opaque"); break;
case Transparency.BITMASK: System.out.println("bitmask"); break;
case Transparency.TRANSLUCENT:
System.out.println("translucent"); break;
}
}
else System.out.println("No color model.");
}
}



Media player

  

/*
 * @(#)MDIApp.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.awt.BorderLayout;
import java.awt.CheckboxMenuItem;
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.EndOfMediaEvent;
import javax.media.Manager;
import javax.media.NoPlayerException;
import javax.media.Player;
import javax.media.PrefetchCompleteEvent;
import javax.media.RealizeCompleteEvent;
import javax.media.Time;
import javax.swing.JDesktopPane;
import javax.swing.JInternalFrame;
import javax.swing.UIManager;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import com.sun.media.ui.MessageBox;
public class MDIApp extends Frame {
    /*************************************************************************
     * MAIN PROGRAM / STATIC METHODS
     *************************************************************************/
    
    public static void main(String args[]) {
    MDIApp mdi = new MDIApp();
    }
    static void Fatal(String s) {
    MessageBox mb = new MessageBox("JMF Error", s);
    }    
    /*************************************************************************
     * VARIABLES
     *************************************************************************/
    
    JMFrame jmframe = null;
    JDesktopPane desktop;
    FileDialog fd = null;
    CheckboxMenuItem cbAutoLoop = null;
    Player player = null;
    Player newPlayer = null;
    String filename;
    
    /*************************************************************************
     * METHODS
     *************************************************************************/
    
    public MDIApp() {
    super("Java Media Player");
    // Add the desktop pane
    setLayout( new BorderLayout() );
    desktop = new JDesktopPane();
    desktop.setDoubleBuffered(true);
    add("Center", desktop);
    setMenuBar(createMenuBar());
    setSize(640, 480);
    setVisible(true);
    
    try {
        UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
    } catch (Exception e) {
        System.err.println("Could not initialize java.awt Metal lnf");
    }
    addWindowListener( new WindowAdapter() {
        public void windowClosing(WindowEvent we) {
        System.exit(0);
        }
    } );
    Manager.setHint(Manager.LIGHTWEIGHT_RENDERER, new Boolean(true));
    }
    
    private MenuBar createMenuBar() {
    ActionListener al = new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
        String command = ae.getActionCommand();
        if (command.equals("Open")) {
            if (fd == null) {
            fd = new FileDialog(MDIApp.this, "Open File",
                               FileDialog.LOAD);
            fd.setDirectory("/movies");
            }
            fd.show();
            if (fd.getFile() != null) {
            String filename = fd.getDirectory() + fd.getFile();
            openFile("file:" + filename);
            }
        } else if (command.equals("Exit")) {
            dispose();
            System.exit(0);
        }
        }
    };
    MenuItem item;
    MenuBar mb = new MenuBar();
    // File Menu
    Menu mnFile = new Menu("File");
    mnFile.add(item = new MenuItem("Open"));
    item.addActionListener(al);
    mnFile.add(item = new MenuItem("Exit"));
    item.addActionListener(al);
    // Options Menu 
    Menu mnOptions = new Menu("Options");
    cbAutoLoop = new CheckboxMenuItem("Auto replay");
    cbAutoLoop.setState(true);
    mnOptions.add(cbAutoLoop);
    
    mb.add(mnFile);
    mb.add(mnOptions);
    return mb;
    }           
    /**
     * Open a media file.
     */
    public void openFile(String filename) {
    String mediaFile = filename;
    Player player = null;
    // URL for our media file
    URL url = null;
    try {
        // Create an url from the file name and the url to the
        // document containing this applet.
        if ((url = new URL(mediaFile)) == null) {
        Fatal("Can"t build URL for " + mediaFile);
        return;
        }
        
        // Create an instance of a player for this media
        try {
        player = Manager.createPlayer(url);
        } catch (NoPlayerException e) {
        Fatal("Error: " + e);
        }
    } catch (MalformedURLException e) {
        Fatal("Error:" + e);
    } catch (IOException e) {
        Fatal("Error:" + e);
    }
    if (player != null) {
        this.filename = filename;
        JMFrame jmframe = new JMFrame(player, filename);
        desktop.add(jmframe);
    }
    }
}
class JMFrame extends JInternalFrame implements ControllerListener {
    Player mplayer;
    Component visual = null;
    Component control = null;
    int videoWidth = 0;
    int videoHeight = 0;
    int controlHeight = 30;
    int insetWidth = 10;
    int insetHeight = 30;
    boolean firstTime = true;
    
    public JMFrame(Player player, String title) {
    super(title, true, true, true, true);
    getContentPane().setLayout( new BorderLayout() );
    setSize(320, 10);
    setLocation(50, 50);
    setVisible(true);
    mplayer = player;
    mplayer.addControllerListener((ControllerListener) this);
    mplayer.realize();
    addInternalFrameListener( new InternalFrameAdapter() {
        public void internalFrameClosing(InternalFrameEvent ife) {
        mplayer.close();
        }
    } );
            
    }
    
    public void controllerUpdate(ControllerEvent ce) {
    if (ce instanceof RealizeCompleteEvent) {
        mplayer.prefetch();
    } else if (ce instanceof PrefetchCompleteEvent) {
        if (visual != null)
        return;
        
        if ((visual = mplayer.getVisualComponent()) != null) {
        Dimension size = visual.getPreferredSize();
        videoWidth = size.width;
        videoHeight = size.height;
        getContentPane().add("Center", visual);
        } else
        videoWidth = 320;
        if ((control = mplayer.getControlPanelComponent()) != null) {
        controlHeight = control.getPreferredSize().height;
        getContentPane().add("South", control);
        }
        setSize(videoWidth + insetWidth,
            videoHeight + controlHeight + insetHeight);
        validate();
        mplayer.start();
    } else if (ce instanceof EndOfMediaEvent) {
        mplayer.setMediaTime(new Time(0));
        mplayer.start();
    }
    }
}



Query the installed version of the JMF

  
/*******************************************************************************
 * GUIManagerQuery - A Graphical User Interface built atop the ManagerQuery
 * class allowing the user to query the installed version of the JMF as to its
 * support in termsof different players, processors, and protocols.
 * 
 * @author Spike Barlow
 ******************************************************************************/
import java.awt.*;
import java.awt.event.*;
import javax.media.*;
import java.util.*;
public class GUIManagerQuery extends Frame implements ActionListener {
  /** The version of the JMF. */
  protected Label versionLabel;
  /** Button to print JMF"s hints. */
  protected Button hintsButton;
  /** Button to print list of players. */
  protected Button playersButton;
  /** Button to print list of processors. */
  protected Button processorsButton;
  /** Button to print list of data sources. */
  protected Button sourcesButton;
  /** TextField in which user can enter protocols or content types. */
  protected TextField contentsField;
  /** Area in which the results are displayed. */
  protected TextArea results;
  /***************************************************************************
   * Construct the GUIManagerQuery object, constructing the various components
   * and laying them out on the screen.
   **************************************************************************/
  public GUIManagerQuery() {
    super("GUIManagerQuery");
    setLayout(new BorderLayout());
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    versionLabel = new Label("JMF v" + Manager.getVersion());
    add(versionLabel, "North");
    Panel lower = new Panel();
    lower.add(new Label("Content/Protocol"));
    contentsField = new TextField(32);
    lower.add(contentsField);
    add(lower, "South");
    results = new TextArea(20, 80);
    results.setEditable(false);
    add(results, "Center");
    Panel controls = new Panel();
    controls.setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    hintsButton = new Button("Hints");
    gbc.gridx = 0;
    gbc.gridy = 0;
    controls.add(hintsButton, gbc);
    hintsButton.addActionListener(this);
    playersButton = new Button("Players");
    gbc.gridy = 1;
    controls.add(playersButton, gbc);
    playersButton.addActionListener(this);
    processorsButton = new Button("Processors");
    gbc.gridy = 2;
    controls.add(processorsButton, gbc);
    processorsButton.addActionListener(this);
    sourcesButton = new Button("DataSources");
    gbc.gridy = 3;
    controls.add(sourcesButton, gbc);
    sourcesButton.addActionListener(this);
    add(controls, "East");
  }
  /***************************************************************************
   * Respond to button presses from the user indicating the desire for
   * information such as a list of players.
   **************************************************************************/
  public void actionPerformed(ActionEvent e) {
    int type;
    String[] cons;
    ////////////////////////////////////////////////////////////////
    // Handle hints - simplest case [no need to check content types]
    ////////////////////////////////////////////////////////////////
    if (e.getSource() == hintsButton) {
      results.setText(ManagerQuery.getHints());
    }
    /////////////////////////////////////////////////////////////////////
    // Players, processors, or datasources. Need to check the contents
    // field and if it has text in there then use that as a qualifier
    // in the search for classes. However if empty then generate a
    // complete list of all classes of the required type. User may
    // enter multiple content types either comma or space separated,
    // hence use of StringTokenizer.
    ////////////////////////////////////////////////////////////////////
    else {
      if (e.getSource() == playersButton)
        type = ManagerQuery.HANDLERS;
      else if (e.getSource() == processorsButton)
        type = ManagerQuery.PROCESSORS;
      else
        type = ManagerQuery.DATASOURCES;
      String contents = contentsField.getText();
      if (contents == null || contents.length() == 0)
        cons = null;
      else {
        StringTokenizer tokenizer = new StringTokenizer(contents,
            " ,\t;");
        cons = new String[tokenizer.countTokens()];
        for (int i = 0; i < cons.length; i++)
          cons[i] = tokenizer.nextToken();
      }
      if (cons != null && cons.length > 0)
        results.setText(ManagerQuery
            .getHandlersOrProcessors(cons, type));
      else if (type == ManagerQuery.HANDLERS)
        results.setText(ManagerQuery.getHandlers());
      else if (type == ManagerQuery.PROCESSORS)
        results.setText(ManagerQuery.getProcessors());
      else
        results.setText(ManagerQuery.getDataSources());
    }
  }
  /***************************************************************************
   * Main method - construct a GUIManagerQuery frame and show it on the
   * screen.
   **************************************************************************/
  public static void main(String[] args) {
    GUIManagerQuery gui = new GUIManagerQuery();
    gui.pack();
    gui.setSize(640, 600);
    gui.show();
  }
}



Renderer for RGB images using AWT Image using Java Media API

  

/*
 * @(#)SampleAWTRenderer.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 javax.media.*;
import javax.media.renderer.VideoRenderer;
import javax.media.Format;
import javax.media.format.VideoFormat;
import javax.media.format.RGBFormat;
import java.awt.*;
import java.awt.image.*;
import java.awt.color.ColorSpace;
import java.awt.event.*;
import java.util.Vector;
/**
 * Renderer for RGB images using AWT Image.
 */
public class SampleAWTRenderer implements javax.media.renderer.VideoRenderer {
    /*************************************************************************
     * Variables and Constants
     *************************************************************************/
    // The descriptive name of this renderer
    private static final String name = "Sample AWT Renderer";
    protected RGBFormat inputFormat;
    protected RGBFormat supportedRGB;
    protected Format[] supportedFormats;
    protected MemoryImageSource sourceImage;
    protected Image destImage;
    protected Buffer lastBuffer = null;
    protected int inWidth = 0;
    protected int inHeight = 0;
    protected Component component = null;
    protected Rectangle reqBounds = null;
    protected Rectangle bounds = new Rectangle();
    protected boolean started = false;
    /*************************************************************************
     * Constructor
     *************************************************************************/
    public SampleAWTRenderer() {
        // Prepare supported input formats and preferred format
        int rMask = 0x000000FF;
        int gMask = 0x0000FF00;
        int bMask = 0x00FF0000;
        supportedRGB = new RGBFormat(null, // size
                Format.NOT_SPECIFIED, // maxDataLength
                int[].class, // buffer type
                Format.NOT_SPECIFIED, // frame rate
                32, // bitsPerPixel
                rMask, gMask, bMask, // component masks
                1, // pixel stride
                Format.NOT_SPECIFIED, // line stride
                Format.FALSE, // flipped
                Format.NOT_SPECIFIED // endian
        );
        supportedFormats = new VideoFormat[1];
        supportedFormats[0] = supportedRGB;
    }
    /****************************************************************
     * Controls implementation
     ****************************************************************/
    /**
     * Returns an array of supported controls
     **/
    public Object[] getControls() {
        // No controls
        return (Object[]) new Control[0];
    }
    /**
     * Return the control based on a control type for the PlugIn.
     */
    public Object getControl(String controlType) {
        try {
            Class cls = Class.forName(controlType);
            Object cs[] = getControls();
            for (int i = 0; i < cs.length; i++) {
                if (cls.isInstance(cs[i]))
                    return cs[i];
            }
            return null;
        } catch (Exception e) { // no such controlType or such control
            return null;
        }
    }
    /*************************************************************************
     * PlugIn implementation
     *************************************************************************/
    public String getName() {
        return name;
    }
    /**
     * Opens the plugin
     */
    public void open() throws ResourceUnavailableException {
        sourceImage = null;
        destImage = null;
        lastBuffer = null;
    }
    /**
     * Resets the state of the plug-in. Typically at end of media or when media
     * is repositioned.
     */
    public void reset() {
        // Nothing to do
    }
    public void close() {
        // Nothing to do
    }
    /*************************************************************************
     * Renderer implementation
     *************************************************************************/
    public void start() {
        started = true;
    }
    public void stop() {
        started = false;
    }
    /**
     * Lists the possible input formats supported by this plug-in.
     */
    public Format[] getSupportedInputFormats() {
        return supportedFormats;
    }
    /**
     * Set the data input format.
     */
    public Format setInputFormat(Format format) {
        if (format != null && format instanceof RGBFormat && format.matches(supportedRGB)) {
            inputFormat = (RGBFormat) format;
            Dimension size = inputFormat.getSize();
            inWidth = size.width;
            inHeight = size.height;
            return format;
        } else
            return null;
    }
    /**
     * Processes the data and renders it to a component
     */
    public synchronized int process(Buffer buffer) {
        if (component == null)
            return BUFFER_PROCESSED_FAILED;
        Format inf = buffer.getFormat();
        if (inf == null)
            return BUFFER_PROCESSED_FAILED;
        if (inf != inputFormat || !buffer.getFormat().equals(inputFormat)) {
            if (setInputFormat(inf) != null)
                return BUFFER_PROCESSED_FAILED;
        }
        Object data = buffer.getData();
        if (!(data instanceof int[]))
            return BUFFER_PROCESSED_FAILED;
        if (lastBuffer != buffer) {
            lastBuffer = buffer;
            newImage(buffer);
        }
        sourceImage.newPixels(0, 0, inWidth, inHeight);
        Graphics g = component.getGraphics();
        if (g != null) {
            if (reqBounds == null) {
                bounds = component.getBounds();
                bounds.x = 0;
                bounds.y = 0;
            } else
                bounds = reqBounds;
            g.drawImage(destImage, bounds.x, bounds.y, bounds.width, bounds.height, 0, 0, inWidth, inHeight, component);
        }
        return BUFFER_PROCESSED_OK;
    }
    /****************************************************************
     * VideoRenderer implementation
     ****************************************************************/
    /**
     * Returns an AWT component that it will render to. Returns null
     * if it is not rendering to an AWT component.
     */
    public java.awt.ruponent getComponent() {
        if (component == null) {
            component = new Canvas() {
                public Dimension getPreferredSize() {
                    return new Dimension(getInWidth(), getInHeight());
                }
                public void update(Graphics g) {
                }
                public void paint(Graphics g) {
                    // TODO: Need to repaint image if the movie is in paused state
                }
            };
        }
        return component;
    }
    /**
     * Requests the renderer to draw into a specified AWT component.
     * Returns false if the renderer cannot draw into the specified
     * component.
     */
    public boolean setComponent(java.awt.ruponent comp) {
        component = comp;
        return true;
    }
    /**
     * Sets the region in the component where the video is to be
     * rendered to. Video is to be scaled if necessary. If <code>rect</code>
     * is null, then the video occupies the entire component.
     */
    public void setBounds(java.awt.Rectangle rect) {
        reqBounds = rect;
    }
    /**
     * Returns the region in the component where the video will be
     * rendered to. Returns null if the entire component is being used.
     */
    public java.awt.Rectangle getBounds() {
        return reqBounds;
    }
    /*************************************************************************
     * Local methods
     *************************************************************************/
    int getInWidth() {
        return inWidth;
    }
    int getInHeight() {
        return inHeight;
    }
    private void newImage(Buffer buffer) {
        
        if (!(buffer.getData() instanceof int[]))
            return;
        int[] data = (int[]) buffer.getData();
        RGBFormat format = (RGBFormat) buffer.getFormat();
        //data = processImage(buffer);
        data = (int[]) buffer.getData();
        DirectColorModel dcm = new DirectColorModel(format.getBitsPerPixel(), format.getRedMask(), format.getGreenMask(), format.getBlueMask());
        sourceImage = new MemoryImageSource(format.getLineStride(), format.getSize().height, dcm, (int[]) data, 0, format.getLineStride());
        sourceImage.setAnimated(true);
        sourceImage.setFullBufferUpdates(true);
        if (component != null) {
            destImage = component.createImage(sourceImage);
            component.prepareImage(destImage, component);
        }
    }
    private int[] processImage(Buffer buf) {
        int[] data = (int[]) buf.getData();
        int[] ret = new int[data.length];
        RGBFormat fmt = (RGBFormat) buf.getFormat();
        DirectColorModel dcm = new DirectColorModel(fmt.getBitsPerPixel(), fmt.getRedMask(), fmt.getGreenMask(), fmt.getBlueMask());
        int[] rgb;
        int k;
        for (int i = 0; i < data.length; i++) {
            rgb = dcm.getComponents(data[i], null, 0);
            k = toGray(rgb);
            rgb[0] = rgb[1] = rgb[2] = k;
            ret[i] = dcm.getDataElement(rgb, 0);
        }
        return ret;
    }
    private int toGray(int[] rgb) {
        return (int) (0.2125 * rgb[0] + 0.7154 * rgb[1] + 0.0721 * rgb[2]);
    }
}



Sample program to demonstrate FramePositioningControl.

  

/*
 * @(#)Seek.java    1.2 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.awt.BorderLayout;
import java.awt.Button;
import java.awt.ruponent;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import javax.media.ConfigureCompleteEvent;
import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.Duration;
import javax.media.EndOfMediaEvent;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.Player;
import javax.media.PrefetchCompleteEvent;
import javax.media.RealizeCompleteEvent;
import javax.media.ResourceUnavailableEvent;
import javax.media.SizeChangeEvent;
import javax.media.Time;
import javax.media.control.FramePositioningControl;
import javax.media.protocol.DataSource;

/**
 * Sample program to demonstrate FramePositioningControl.
 */
public class Seek extends Frame implements ControllerListener, ActionListener {
    Player p;
    FramePositioningControl fpc;
    Object waitSync = new Object();
    boolean stateTransitionOK = true;
    int totalFrames = FramePositioningControl.FRAME_UNKNOWN;
    Panel cntlPanel;
    Button fwdButton;
    Button bwdButton;
    Button rndButton;
    /**
     * Given a DataSource, create a player and use that player
     * as a player to playback the media.
     */
    public boolean open(DataSource ds) {
    System.err.println("create player for: " + ds.getContentType());
    try {
        p = Manager.createPlayer(ds);
    } catch (Exception e) {
        System.err.println("Failed to create a player from the given DataSource: " + e);
        return false;
    }
    p.addControllerListener(this);
    p.realize();
    if (!waitForState(p.Realized)) {
        System.err.println("Failed to realize the player.");
        return false;
    }
    // Try to retrieve a FramePositioningControl from the player.
    fpc = (FramePositioningControl)p.getControl("javax.media.control.FramePositioningControl");
    if (fpc == null) {
        System.err.println("The player does not support FramePositioningControl.");
        System.err.println("There"s no reason to go on for the purpose of this demo.");
        return false;
    }
    Time duration = p.getDuration();
    if (duration != Duration.DURATION_UNKNOWN) {
        System.err.println("Movie duration: " + duration.getSeconds());
        totalFrames = fpc.mapTimeToFrame(duration);
        if (totalFrames != FramePositioningControl.FRAME_UNKNOWN)
        System.err.println("Total # of video frames in the movies: " + totalFrames);
        else
        System.err.println("The FramePositiongControl does not support mapTimeToFrame.");
    } else {
        System.err.println("Movie duration: unknown"); 
    }
    
    // Prefetch the player.
    p.prefetch();
    if (!waitForState(p.Prefetched)) {
        System.err.println("Failed to prefetch the player.");
        return false;
    }
    // Display the visual & control component if there"s one.
    setLayout(new BorderLayout());
    cntlPanel = new Panel();
    fwdButton = new Button("Forward");
    bwdButton = new Button("Backward");
    rndButton = new Button("Random");
    fwdButton.addActionListener(this);
    bwdButton.addActionListener(this);
    rndButton.addActionListener(this);
    cntlPanel.add(fwdButton);
    cntlPanel.add(bwdButton);
    cntlPanel.add(rndButton);
    Component vc;
    if ((vc = p.getVisualComponent()) != null) {
        add("Center", vc);
    }
    add("South", cntlPanel);
    setVisible(true);
    return true;
    }

    public void addNotify() {
    super.addNotify();
    pack();
    }

    /**
     * Block until the player has transitioned to the given state.
     * Return false if the transition failed.
     */
    boolean waitForState(int state) {
    synchronized (waitSync) {
        try {
        while (p.getState() < state && stateTransitionOK)
            waitSync.wait();
        } catch (Exception e) {}
    }
    return stateTransitionOK;
    }

    public void actionPerformed(ActionEvent ae) {
    String command = ae.getActionCommand();
    if (command.equals("Forward")) {
        int dest = fpc.skip(1);
        System.err.println("Step forward " + dest + " frame.");
    } else if (command.equals("Backward")) {
        int dest = fpc.skip(-1);
        System.err.println("Step backward " + dest + " frame.");
    } else if (command.equals("Random")) {
        if (totalFrames == FramePositioningControl.FRAME_UNKNOWN)
        System.err.println("Cannot jump to a random frame.");
        else {
        int randomFrame = (int)(totalFrames * Math.random());
        randomFrame = fpc.seek(randomFrame);
        System.err.println("Jump to a random frame: " + randomFrame);
        }
    }
    int currentFrame = fpc.mapTimeToFrame(p.getMediaTime());
    if (currentFrame != FramePositioningControl.FRAME_UNKNOWN)
        System.err.println("Current frame: " + currentFrame);
    }

    /**
     * Controller Listener.
     */
    public void controllerUpdate(ControllerEvent evt) {
    if (evt instanceof ConfigureCompleteEvent ||
        evt instanceof RealizeCompleteEvent ||
        evt instanceof PrefetchCompleteEvent) {
        synchronized (waitSync) {
        stateTransitionOK = true;
        waitSync.notifyAll();
        }
    } else if (evt instanceof ResourceUnavailableEvent) {
        synchronized (waitSync) {
        stateTransitionOK = false;
        waitSync.notifyAll();
        }
    } else if (evt instanceof EndOfMediaEvent) {
        p.setMediaTime(new Time(0));
        //p.start();
        //p.close();
        //System.exit(0);
    } else if (evt instanceof SizeChangeEvent) {
    }
    }

    /**
     * Main program
     */
    public static void main(String [] args) {
    if (args.length == 0) {
        prUsage();
        System.exit(0);
    }
    MediaLocator ml;
    if ((ml = new MediaLocator(args[0])) == null) {
        System.err.println("Cannot build media locator from: " + args[0]);
        prUsage();
        System.exit(0);
    }
    
    DataSource ds = null;
    // Create a DataSource given the media locator.
    try {
        ds = Manager.createDataSource(ml);
    } catch (Exception e) {
        System.err.println("Cannot create DataSource from: " + ml);
        System.exit(0);
    }
    Seek seek = new Seek();
    if (!seek.open(ds))
        System.exit(0);
    }
    static void prUsage() {
    System.err.println("Usage: java Seek <url>");
    }
}



Select a media file from tjelocal file system and gain statistics

  
/**********************************************************************
* GUIMediaStatistics - a GUI allowing the user to select a media
* file from tjelocal file system and gain statistics on that media
* (audio or video) concerning its tracks and their format/composition.
*
* The class is built atop the MediaStatistics class and arguably
* provides a more user friendly mechanism for determining the
*format of media.
*
* @author Spike Barlow
***********************************************************************/
import java.awt.*;
import java.awt.event.*;
import javax.media.*;
import java.util.*;
public class GUIMediaStatistics extends Frame implements ActionListener {
  /** Object to determine the format ofthe media. Performs all the real work. */
  protected MediaStatistics     stats;
  /** User wants to search for a file. */
  protected Button              browseButton;
  /** User wants to know the format of the current file. */
  protected Button              getStatsButton;
  /** Current state of processing. */
  protected int                 state;
  /** Where the format informationis displayed. */
  protected TextArea            results;
  /** Area i which the user can type the name of a file. */
  protected TextField           mediaField;
  /** Pause in milliseconds between checks to see if format is known. */
  public static final int       PAUSE = 50;
  /** Maximum wait before giving up on determining theformat. */
  public static final int       MAX_WAIT_PERIOD = 10000;
  /** Directory that the user last searched for files. */
  protected String              lastDirectory;


/**********************************************************************
* Construct the GUIMediaStatistics object, constructing the various
* components and laying them out on the screen.
**********************************************************************/
public GUIMediaStatistics() {
  super("GUIMediaStatistics");
  setLayout(new BorderLayout());
  addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
      System.exit(0); } });
  Panel filePanel = new Panel();
  filePanel.add(new Label("File:"));
  mediaField = new TextField(40);
  filePanel.add(mediaField);
  browseButton =new Button("browse...");
  filePanel.add(browseButton);
  browseButton.addActionListener(this);
  getStatsButton = new Button("get stats...");
  filePanel.add(getStatsButton);
  getStatsButton.addActionListener(this);
  add(filePanel,"North");
  results = new TextArea(80,10);
  results.setEditable(false);
  add(results,"Center");
}

/************************************************************************
* Respond to user button presses - either browsing for a file or
* gathering format info on the current file.
************************************************************************/
public void actionPerformed(ActionEvent e) {
    /////////////////////////////////
    // Browse - use FileDialog class.
    /////////////////////////////////
    if (e.getSource() == browseButton) {
      FileDialog choice = new FileDialog(this, "Media File Choice",
          FileDialog.LOAD);
      if (lastDirectory != null)
        choice.setDirectory(lastDirectory);
      choice.show();
      String selection = choice.getFile();
      if (selection != null) {
        lastDirectory = choice.getDirectory();
        mediaField.setText("file://" + choice.getDirectory()
            + selection);
      }
    }
    ////////////////////////////////////////////////////////
    // Get statistics - create a MediaStatistics object and
    // monitor its progress.
    ///////////////////////////////////////////////////////
    else {
      stats = new MediaStatistics(mediaField.getText());
      monitorAndReport();
    }
  }
  /************************************************************************
   * Monitor the progress of the MediaStatistics object as it attempts to
   * determineformatinformation for the current file. It periodically
   * polls the object, obtaining a report from it and printing it to the
   * screen. The polling stops as soon as the format is known, it is
   * found that it isimpossible to determine a format, or a certain time
   * period is exceeded.
   **************************************************************************/
  private void monitorAndReport() {
    int elapsed = 0;
    state = stats.getState();
    while (elapsed < MAX_WAIT_PERIOD
        && (state != MediaStatistics.FAILED && state != MediaStatistics.KNOWN)) {
      results.setText(stats.getReport());
      try {
        Thread.sleep(PAUSE);
      } catch (Exception e) {
      }
      elapsed += PAUSE;
      state = stats.getState();
    }
    if (state == MediaStatistics.FAILED || state == MediaStatistics.KNOWN)
      results.setText(stats.getReport());
    else
      results.setText("Timing out after maximum period of "
          + MAX_WAIT_PERIOD + "ms");
  }
  /***************************************************************************
   * Main method - construct a GUIMediaStatistics frame and show it on the
   * screen.
   **************************************************************************/
  public static void main(String[] args) {
    GUIMediaStatistics gui = new GUIMediaStatistics();
    gui.pack();
    gui.setSize(600, 400);
    gui.show();
  }
}