001/*
002 *   PNGImageObserver -- Image observer that turns an image into a PNG file.
003 *   
004 *   Copyright (C) 2009-2014 by Joseph A. Huwaldt.
005 *   All rights reserved.
006 *   
007 *   This library is free software; you can redistribute it and/or
008 *   modify it under the terms of the GNU Lesser General Public
009 *   License as published by the Free Software Foundation; either
010 *   version 2.1 of the License, or (at your option) any later version.
011 *   
012 *   This library is distributed in the hope that it will be useful,
013 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
014 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015 *   Lesser General Public License for more details.
016 *
017 *   You should have received a copy of the GNU Lesser General Public License
018 *   along with this program; if not, write to the Free Software
019 *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
020 *   Or visit:  http://www.gnu.org/licenses/lgpl.html
021 *
022 *   This is based on JPEGImageObserver from the org.j3d package which included
023 *   the following note:
024 *
025 *                        J3D.org Copyright (c) 2000
026 *                               Java Source
027 *
028 * This source is licensed under the GNU LGPL v2.1
029 */
030package jahuwaldt.j3d.image;
031
032import jahuwaldt.image.encoders.ImageEncoder;
033import jahuwaldt.image.encoders.JPEGEncoderAdapter;
034import java.util.ResourceBundle;
035import java.awt.image.BufferedImage;
036import java.io.File;
037import java.io.FileOutputStream;
038import java.io.IOException;
039import java.text.MessageFormat;
040
041/**
042 * An image observer that turns the image into a JPEG image. <p> If the filename already
043 * exists, it will automatically overwrite the existing image. If the filename contains
044 * non-existent intermediate directories, these will be automatically created. </p>
045 *
046 * <p> Modified by: Joseph A.Huwaldt </p>
047 *
048 * @author Justin Couch
049 * @version February 17, 2014
050 */
051public class JPEGImageObserver implements CapturedImageObserver {
052
053    /**
054     * The resource bundle for this package.
055     */
056    protected static final ResourceBundle RESOURCES =
057            ResourceBundle.getBundle("jahuwaldt.j3d.image.J3DImage", java.util.Locale.getDefault());
058    /**
059     * A flag to indicate we should capture the next frame
060     */
061    private boolean captureNextFrame = false;
062    /**
063     * The currently set filename.
064     */
065    private String filename;
066
067    /**
068     * Construct a default observer with no filename set and it has not yet captured an
069     * image.
070     */
071    public JPEGImageObserver() { }
072
073    /**
074     * Tell the observer to capture the next frame it is told about. If the observer has
075     * already fired, it will throw an IllegalStateException.
076     */
077    public synchronized void setCaptureNextFrame() {
078        captureNextFrame = true;
079    }
080
081    /**
082     * Returns a flag indicating if the next frame should be captured or not.
083     *
084     * @return <code>true</code> if the observer should be passed an image for the next
085     * frame and <code>false</code> if it should not.
086     */
087    @Override
088    public boolean captureNextFrame() {
089        return captureNextFrame;
090    }
091
092    /**
093     * Set the filename that this will write to. If the filename is null, this will remove
094     * the previously set name. It can only be set if the image has not yet been captured.
095     *
096     * @param name The name of the file to write to.
097     */
098    public synchronized void setFilename(String name) throws IllegalStateException {
099        filename = name;
100    }
101
102    /**
103     * Notification that an image has been captured from the canvas and is ready for
104     * processing. If the filename has not been set then this will throw an exception.
105     *
106     * @param img The image that was captured
107     * @throws IllegalStateException The filename has not been set
108     */
109    @Override
110    public synchronized void canvasImageCaptured(BufferedImage img) {
111        if (!captureNextFrame)
112            return;
113        captureNextFrame = false;
114
115        if (filename == null)
116            throw new IllegalStateException(RESOURCES.getString("noFileName"));
117
118        FileOutputStream out = null;
119        try {
120            File file = new File(filename);
121
122            File dirs = file.getParentFile();
123            dirs.mkdirs();
124
125            out = new FileOutputStream(file);
126            ImageEncoder encoder = new JPEGEncoderAdapter();
127
128            encoder.encode(img, out);
129
130        } catch (IOException e) {
131            System.out.println(MessageFormat.format(RESOURCES.getString("ioExceptionWriting"), "JPEG"));
132            e.printStackTrace();
133        } finally {
134            if (out != null)
135                try {
136                    out.close();
137                } catch (IOException e) {
138                }
139        }
140
141    }
142}