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.PNGEncoderAdapter;
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 PNG image.
043 * <p>
044 * If the filename already exists, it will automatically overwrite the existing image. 
045 * If the filename contains non-existent intermediate directories, these will be 
046 * automatically created.
047 * </p>
048 *
049 * <p> Modified by: Joseph A.Huwaldt </p>
050 *
051 * @author Joseph A. Huwaldt Date: April 16, 2009
052 * @version February 17, 2014
053 */
054public class PNGImageObserver implements CapturedImageObserver {
055
056    /**
057     * The resource bundle for this package.
058     */
059    protected static final ResourceBundle RESOURCES =
060            ResourceBundle.getBundle("jahuwaldt.j3d.image.J3DImage", java.util.Locale.getDefault());
061    /**
062     * A flag to indicate we should capture the next frame
063     */
064    private boolean captureNextFrame = false;
065    /**
066     * The currently set filename.
067     */
068    private String filename;
069
070    /**
071     * Construct a default observer with no filename set and it has not yet captured an
072     * image.
073     */
074    public PNGImageObserver() { }
075
076    /**
077     * Tell the observer to capture the next frame it is told about.
078     */
079    public synchronized void setCaptureNextFrame() {
080        captureNextFrame = true;
081    }
082
083    /**
084     * Returns a flag indicating if the next frame should be captured or not.
085     *
086     * @return <code>true</code> if the observer should be passed an image for the next
087     * frame and <code>false</code> if it should not.
088     */
089    @Override
090    public boolean captureNextFrame() {
091        return captureNextFrame;
092    }
093
094    /**
095     * Set the filename that this will write to. If the filename is null, this will remove
096     * the previously set name. It can only be set if the image has not yet been captured.
097     *
098     * @param name The name of the file to write to.
099     */
100    public synchronized void setFilename(String name) throws IllegalStateException {
101        filename = name;
102    }
103
104    /**
105     * Notification that an image has been captured from the canvas and is ready for
106     * processing. If the filename has not been set then this will throw an exception.
107     *
108     * @param img The image that was captured
109     * @throws IllegalStateException The filename has not been set
110     */
111    @Override
112    public synchronized void canvasImageCaptured(BufferedImage img) {
113        if (!captureNextFrame)
114            return;
115        captureNextFrame = false;
116
117        if (filename == null)
118            throw new IllegalStateException(RESOURCES.getString("noFileName"));
119
120        FileOutputStream out = null;
121        try {
122            File file = new File(filename);
123
124            File dirs = file.getParentFile();
125            dirs.mkdirs();
126
127            out = new FileOutputStream(file);
128            ImageEncoder encoder = new PNGEncoderAdapter();
129
130            encoder.encode(img, out);
131
132        } catch (IOException e) {
133            System.out.println(MessageFormat.format(RESOURCES.getString("ioExceptionWriting"), "PNG"));
134            e.printStackTrace();
135        } finally {
136            if (out != null)
137                try {
138                    out.close();
139                } catch (IOException e) {
140                }
141        }
142
143    }
144}