303 lines
7.5 KiB
Java
303 lines
7.5 KiB
Java
/*
|
|
|
|
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
|
|
|
This file is part of C.a.R. software.
|
|
|
|
C.a.R. is a free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, version 3 of the License.
|
|
|
|
C.a.R. is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
package rene.util;
|
|
|
|
import java.awt.Color;
|
|
import java.awt.Font;
|
|
import java.awt.FontMetrics;
|
|
import java.awt.Frame;
|
|
import java.awt.Graphics;
|
|
import java.awt.Image;
|
|
import java.awt.event.WindowAdapter;
|
|
import java.awt.event.WindowEvent;
|
|
import java.awt.event.WindowListener;
|
|
import java.awt.image.ImageObserver;
|
|
import java.awt.image.MemoryImageSource;
|
|
import java.awt.image.PixelGrabber;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.util.Calendar;
|
|
|
|
/**
|
|
* TestEncoder creates a PNG file that shows an analog clock displaying the
|
|
* current time of day, optionally with an alpha channel, and with the specified
|
|
* filter.
|
|
*
|
|
* The file name is in the format:
|
|
*
|
|
* clockHHMM_fNC alphaclockDHHMM_fNC
|
|
*
|
|
* HH = hours (24-hour clock), MM = minutes,
|
|
*
|
|
* N = filter level (0, 1, or 2) C = compression level (0 to 9)
|
|
*
|
|
* "alpha" is prefixed to the name if alpha encoding was used.
|
|
*
|
|
* This test program was written in a burning hurry, so it is not a model of
|
|
* efficient, or even good, code. Comments and bug fixes should be directed to:
|
|
*
|
|
* david@catcode.com
|
|
*
|
|
* @author J. David Eisenberg
|
|
* @version 1.3, 6 April 2000
|
|
*/
|
|
|
|
public class TestEncoder extends Frame {
|
|
/**
|
|
*
|
|
*/
|
|
private static final long serialVersionUID = 1L;
|
|
String message;
|
|
String timeStr;
|
|
Image clockImage = null;
|
|
int hour, minute;
|
|
boolean encodeAlpha;
|
|
int filter;
|
|
int compressionLevel;
|
|
int pixelDepth;
|
|
String filename;
|
|
boolean fileSaved = false;
|
|
|
|
public TestEncoder(final String s) {
|
|
super(s);
|
|
setSize(200, 200);
|
|
}
|
|
|
|
public void drawClockImage(int hour, final int minute) {
|
|
// variables used for drawing hands of clock
|
|
Graphics g;
|
|
final Font smallFont = new Font("Helvetica", Font.PLAIN, 9);
|
|
FontMetrics fm;
|
|
|
|
int x0, y0, x1, y1;
|
|
double angle;
|
|
|
|
g = clockImage.getGraphics();
|
|
g.setFont(smallFont);
|
|
fm = g.getFontMetrics();
|
|
|
|
// draw the clock face; yellow for AM, blue for PM
|
|
if (hour < 12) {
|
|
g.setColor(new Color(255, 255, 192));
|
|
} else {
|
|
g.setColor(new Color(192, 192, 255));
|
|
}
|
|
g.fillOval(10, 10, 80, 80);
|
|
g.setColor(Color.black);
|
|
g.drawOval(10, 10, 80, 80);
|
|
g.drawOval(48, 48, 4, 4);
|
|
|
|
/* draw the 12 / 3 / 6/ 9 numerals */
|
|
g.setFont(smallFont);
|
|
g.drawString("12", 50 - fm.stringWidth("12") / 2, 11 + fm.getAscent());
|
|
g.drawString("3", 88 - fm.stringWidth("3"), 50 + fm.getAscent() / 2);
|
|
g.drawString("6", 50 - fm.stringWidth("6") / 2, 88);
|
|
g.drawString("9", 12, 50 + fm.getAscent() / 2);
|
|
|
|
x0 = 50;
|
|
y0 = 50;
|
|
|
|
/* draw the hour hand */
|
|
hour %= 12;
|
|
angle = -(hour * 30 + minute / 2) + 90;
|
|
angle = angle * (Math.PI / 180.0);
|
|
|
|
x1 = (int) (x0 + 28 * (Math.cos(angle)));
|
|
y1 = (int) (y0 - 28 * (Math.sin(angle)));
|
|
g.drawLine(x0, y0, x1, y1);
|
|
|
|
/* and the minute hand */
|
|
angle = -(minute * 6) + 90;
|
|
angle = angle * Math.PI / 180.0;
|
|
x1 = (int) (x0 + 35 * (Math.cos(angle)));
|
|
y1 = (int) (y0 - 35 * (Math.sin(angle)));
|
|
g.drawLine(x0, y0, x1, y1);
|
|
}
|
|
|
|
public void addAlphaToImage() {
|
|
final int width = 100;
|
|
final int height = 100;
|
|
int alphaMask = 0;
|
|
final int[] pixels = new int[width * height];
|
|
|
|
final PixelGrabber pg = new PixelGrabber(clockImage, 0, 0, width,
|
|
height, pixels, 0, width);
|
|
try {
|
|
pg.grabPixels();
|
|
} catch (final InterruptedException e) {
|
|
System.err.println("interrupted waiting for pixels!");
|
|
return;
|
|
}
|
|
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
|
|
System.err.println("image fetch aborted or errored");
|
|
return;
|
|
}
|
|
for (int i = 0; i < width * height; i++) {
|
|
if ((i % width) == 0) {
|
|
alphaMask = (alphaMask >> 24) & 0xff;
|
|
alphaMask += 2;
|
|
if (alphaMask > 255) {
|
|
alphaMask = 255;
|
|
}
|
|
alphaMask = (alphaMask << 24) & 0xff000000;
|
|
}
|
|
pixels[i] = (pixels[i] & 0xffffff) | alphaMask;
|
|
}
|
|
clockImage = createImage(new MemoryImageSource(width, height, pixels,
|
|
0, width));
|
|
}
|
|
|
|
@Override
|
|
public void paint(final Graphics g) {
|
|
if (clockImage == null) {
|
|
clockImage = createImage(100, 100);
|
|
}
|
|
if (clockImage != null) {
|
|
if (!fileSaved) {
|
|
drawClockImage(hour, minute);
|
|
if (encodeAlpha) {
|
|
addAlphaToImage();
|
|
}
|
|
saveClockImage();
|
|
fileSaved = true;
|
|
}
|
|
g.drawImage(clockImage, 50, 20, null);
|
|
}
|
|
if (message != null) {
|
|
g.drawString(message, 10, 140);
|
|
}
|
|
}
|
|
|
|
protected static void usage() {
|
|
System.out.print("Usage: TestEncoder -alpha -filter n -compress c");
|
|
System.out.println("-alpha means to use alpha encoding (default none)");
|
|
System.out.println("n is filter number 0=none (default), 1=sub, 2=up");
|
|
System.out.println("c is compression factor (0-9); 1 default");
|
|
System.exit(0);
|
|
}
|
|
|
|
public static void main(final String[] args) {
|
|
int i;
|
|
|
|
final TestEncoder te = new TestEncoder("Test PNG Alpha/Filter Encoder");
|
|
i = 0;
|
|
te.encodeAlpha = false;
|
|
te.filter = 0;
|
|
te.pixelDepth = 24;
|
|
te.compressionLevel = 1;
|
|
while (i < args.length) {
|
|
if (args[i].equals("-alpha")) {
|
|
te.encodeAlpha = true;
|
|
i++;
|
|
} else if (args[i].equals("-filter")) {
|
|
if (i != args.length - 1) {
|
|
try {
|
|
te.filter = Integer.parseInt(args[i + 1]);
|
|
} catch (final Exception e) {
|
|
usage();
|
|
break;
|
|
}
|
|
}
|
|
i += 2;
|
|
} else if (args[i].equals("-compress")) {
|
|
if (i != args.length - 1) {
|
|
try {
|
|
te.compressionLevel = Integer.parseInt(args[i + 1]);
|
|
} catch (final Exception e) {
|
|
usage();
|
|
break;
|
|
}
|
|
}
|
|
i += 2;
|
|
} else {
|
|
usage();
|
|
break;
|
|
}
|
|
}
|
|
if (te.pixelDepth == 8) {
|
|
te.encodeAlpha = false;
|
|
}
|
|
te.doYourThing();
|
|
}
|
|
|
|
public void doYourThing() {
|
|
final Calendar cal = Calendar.getInstance();
|
|
|
|
hour = cal.get(Calendar.HOUR);
|
|
if (cal.get(Calendar.AM_PM) == 1) {
|
|
hour += 12;
|
|
}
|
|
hour %= 24;
|
|
minute = cal.get(Calendar.MINUTE);
|
|
|
|
/*
|
|
* format the time to a string of the form hhmm for use in the filename
|
|
*/
|
|
|
|
timeStr = Integer.toString(minute);
|
|
if (minute < 10) {
|
|
timeStr = "0" + timeStr;
|
|
}
|
|
timeStr = Integer.toString(hour) + timeStr;
|
|
if (hour < 10) {
|
|
timeStr = "0" + timeStr;
|
|
}
|
|
|
|
filename = (encodeAlpha) ? "alphaclock" : "clock";
|
|
filename += timeStr + "_f" + filter + compressionLevel + ".png";
|
|
|
|
message = "File: " + filename;
|
|
|
|
final WindowListener l = new WindowAdapter() {
|
|
@Override
|
|
public void windowClosing(final WindowEvent e) {
|
|
System.exit(0);
|
|
}
|
|
};
|
|
addWindowListener(l);
|
|
setVisible(true);
|
|
// show();
|
|
}
|
|
|
|
public void saveClockImage() {
|
|
byte[] pngbytes;
|
|
final PngEncoder png = new PngEncoder(clockImage,
|
|
(encodeAlpha) ? PngEncoder.ENCODE_ALPHA : PngEncoder.NO_ALPHA,
|
|
filter, compressionLevel);
|
|
|
|
try {
|
|
final FileOutputStream outfile = new FileOutputStream(filename);
|
|
pngbytes = png.pngEncode();
|
|
if (pngbytes == null) {
|
|
System.out.println("Null image");
|
|
} else {
|
|
outfile.write(pngbytes);
|
|
}
|
|
outfile.flush();
|
|
outfile.close();
|
|
} catch (final IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
}
|