finalizing camera api, added source(), settings(), and format().. also

fixed unhex
This commit is contained in:
benfry
2005-04-16 08:54:51 +00:00
parent bd94a9e597
commit 2ce33469fe
6 changed files with 187 additions and 139 deletions

View File

@@ -175,10 +175,6 @@ and we don't recommend it at all. nor do we particularly recommend
10.2, if you can avoid it. and if you're running 10.4, processing is
the least of your worries.
mouse wheel support only works if you're using java 1.4. the latest
version of java will be available via the software update control
panel.
serial port.. we use rxtx (version 2.1_6) to handle serial i/o, which
is included with the processing release. unlike previous releases
(anything before 57), it no longer requires separate installation.

View File

@@ -40,12 +40,35 @@ ABOUT REV 0083 -
+ shininess(float shiney) takes a float from 0..1 to specify
the level of shininess for the current material
- video camera api should now be finalized:
+ that whole thing with passing null or "" to the camera constructor
was really silly. now either one will just give you the default
video input device.
+ added settings() which will show the settings dialog
+ source() takes parameters TUNER, COMPOSITE, SVIDEO or COMPONENT
to select the input source.
+ format() takes parameters NTSC, SECAM or PAL
+ crop(x, y, w, h) (uses the current imageMode from the parent
applet) will crop the video before putting it into its PImage.
this is almost always used internally because qt likes to add
black bars to the image, but you can now specify your own
settings to crop things further
+ noCrop() will remove any cropping, providing a speed increase.
+ there may be bugs.. things were sometimes hanging on my machine
when there were errors
- link() now works when running as an application. also added
open(String filename) which will attempt to launch an application
using the shell, or open(String args[]) which will do the same
with several command line args.
-
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

View File

@@ -4706,7 +4706,8 @@ public class PApplet extends Applet
}
static final public int unhex(String what) {
return Integer.parseInt(what, 16);
// has to parse as a Long so that it'll work for numbers bigger than 2^31
return (int) (Long.parseLong(what, 16));
}
//

View File

@@ -131,6 +131,7 @@ o yes, and add nf(int what) so that non-padded version works
o but don't put commas into the zero-padded version
o make nf/nfs/nfp not so weird
o nf(PLUS, ...) nf(PAD, ...) nfc(PLUS, ...)
X unhex was broken for numbers bigger than 2^31
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

View File

@@ -9,24 +9,38 @@ X get latest sonia from amit
X remove particles from current processing
X move netscape library out of libs and into build/shared
X add serial.stop() just like client/server
X border weirdness in PdeEditor panels on windows (fixed in 82)
o fix macos readme about how to boost memory size, and 1.3 vs 1.4
X actually, this was already in there
camera
o setting the camera should be an index from list()
o there might be multiple cameras with the same name
X no can do, the function takes a String for the device name
o list() should return full list with all sub-components
X find the example code from the board
X grabbing sub-devices from camera in the lib (via list() or whatever)
o actually, need to use numbered indices (multiple w/ same name)
o list should be: "0 - Logitech QuickCam (Blah)"
o and then use the indices (or the str i guess) to choose
X format(NTSC) or PAL or SECAM
X source(COMPOSITE) or SVIDEO or COMPONENT
X settings() brings up settings dialog
_ rename video.Camera to video.Video ?
_ VideoInput VideoOutput, SoundInput, SoundOutput or AudioInput/AudioOutput
_ list() should return full list with all sub-components
_ find the example code from the board
_ add prompt() method to Camera ("" means default, null is prompt)
_ let them pass in prompt(), not use null
_ setting the camera should be an index from list()
_ grabbing sub-devices from camera in the lib (via list() or whatever)
_ actually, need to use numbered indices (multiple w/ same name)
_ list should be: "0 - Logitech QuickCam (Blah)"
_ and then use the indices (or the str i guess) to choose
_ null is only bringing up settings dialog, that's wrong
_ port DbnRecorder?
_ do this after beta, not likely to work with java 1.4 on macosx
_ add prompt() method to serial
_ remove PdeXxx prefixes on names, make PdeBase into just "Processing"
_ fix macos readme about how to boost memory size, and 1.3 vs 1.4
_ update .exe to use new class/package
_ update .app to use new class/package
_ update linux build and shell scripts for new package
@@ -34,9 +48,6 @@ _ update linux build and shell scripts for new package
_ make a linux version
_ need to fix up the make/dist scripts for linux
fixed in 82
X border weirdness in PdeEditor panels on windows
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

View File

@@ -35,15 +35,26 @@ import quicktime.std.sg.*;
import quicktime.util.RawEncodedImage;
// this is the useful ref page
// http://developer.apple.com/documentation/Java/Reference/1.4.1/Java141API_QTJ/constant-values.html
public class Camera extends PImage implements Runnable {
//implements StdQTConstants, StdQTConstants4, Runnable {
// there are more, but these are all we'll provide for now
static public final int COMPOSITE = StdQTConstants.compositeIn; // 0
static public final int SVIDEO = StdQTConstants.sVideoIn; // 1
static public final int COMPONENT = StdQTConstants.rgbComponentIn; // 2
static public final int TUNER = StdQTConstants.tvTunerIn; // 6
static public final int NTSC = StdQTConstants.ntscIn;
static public final int PAL = StdQTConstants.palIn;
static public final int SECAM = StdQTConstants.secamIn;
PApplet parent;
Method cameraEventMethod;
String name; // keep track for error messages
String name; // keep track for error messages (unused)
Thread runner;
//PImage borderImage;
//boolean removeBorders = true;
boolean available = false;
/** Temporary storage for the raw image data read directly from the camera */
@@ -53,18 +64,24 @@ public class Camera extends PImage implements Runnable {
public int dataHeight;
public int dataRowBytes;
/** True if this image is currently being cropped */
public boolean crop;
public int cropX;
public int cropY;
public int cropW;
public int cropH;
int fps;
RawEncodedImage raw;
SequenceGrabber capture;
public int framerate;
public RawEncodedImage raw;
public SequenceGrabber capture;
/** the guy who's doing all the work */
public SGVideoChannel channel;
static {
//System.out.println("Camera init");
try {
QTSession.open();
} catch (QTException e) {
@@ -81,11 +98,11 @@ public class Camera extends PImage implements Runnable {
public Camera(PApplet parent, int requestWidth, int requestHeight) {
this(parent, "", requestWidth, requestHeight, 30);
this(parent, null, requestWidth, requestHeight, 30);
}
public Camera(PApplet parent, int reqWidth, int reqHeight, int fps) {
this(parent, "", reqWidth, reqHeight, fps);
public Camera(PApplet parent, int reqWidth, int reqHeight, int framerate) {
this(parent, null, reqWidth, reqHeight, framerate);
}
public Camera(PApplet parent, String name, int reqWidth, int reqHeight) {
@@ -93,26 +110,10 @@ public class Camera extends PImage implements Runnable {
}
/*
quicktime.QTSession.open();
quicktime.std.sg.SequenceGrabber sg = new quicktime.std.sg.SequenceGrabber();
quicktime.std.sg.SGVideoChannel sc = new quicktime.std.sg.SGVideoChannel(sg);
quicktime.std.sg.VideoDigitizer vd = sc.getDigitizerComponent();
println( "dv.getNumberOfInputs :" ); println( vd.getNumberOfInputs() ); println();
//change line below to set input source
vd.setInput(1);
//
println( "dv.getInput :" ); println( vd.getInput() ); println();
} catch (Exception e) {
e.printStackTrace();
}
*/
/**
* If 'name' is the empty string, don't set a specific device,
* which means that QuickTime will use that last device used by
* a QuickTime application. If name is set to null, a prompt
* will show up, allowing the user to choose the good stuff.
* If 'name' is null or the empty string, it won't set a specific
* device, which means that QuickTime will use that last device
* used by a QuickTime application.
* <P>
* If the following function:
* public void cameraEvent(Camera c)
@@ -120,100 +121,48 @@ public class Camera extends PImage implements Runnable {
* time a new frame is available from the camera.
*/
public Camera(PApplet parent, String name,
int requestWidth, int requestHeight, int fps) {
int requestWidth, int requestHeight, int framerate) {
this.parent = parent;
this.name = name;
this.fps = fps;
this.framerate = framerate;
try {
/*
QTSession.open();
QTRuntimeException.registerHandler(new QTRuntimeHandler() {
public void exceptionOccurred(QTRuntimeException e,
Object obj, String s, boolean flag) {
System.err.println("Problem inside Camera");
e.printStackTrace();
}
});
*/
//System.out.println("0");
QDRect qdrect = new QDRect(requestWidth, requestHeight);
QDGraphics qdgraphics = new QDGraphics(qdrect);
//System.out.println("0a");
capture = new SequenceGrabber();
//System.out.println("0b");
capture.setGWorld(qdgraphics, null);
//System.out.println("0c");
// CRASHING HERE ON OSX
SGVideoChannel channel = new SGVideoChannel(capture);
//System.out.println("0c1");
channel = new SGVideoChannel(capture);
channel.setBounds(qdrect);
//System.out.println("0c2");
channel.setUsage(2); // what is this usage number?
//System.out.println("0c3");
capture.startPreview(); // maybe this comes later?
//System.out.println("0d");
PixMap pixmap = qdgraphics.getPixMap();
raw = pixmap.getPixelData();
//System.out.println("0e");
/*
if (name == null) {
channel.settingsDialog();
} else if (name.length() > 0) {
channel.setDevice(name);
}
//System.out.println("0f");
//channel.setDevice("Logitech QuickCam Express-WDM");
/*
if (showDialog) channel.settingsDialog();
SGDeviceList list = channel.getDeviceList(0);
System.out.println("count is " + list.getCount());
for (int i = 0; i < list.getCount(); i++) {
System.out.println(list.getDeviceName(i).getName());
}
//System.out.println(channel.getSettings());
*/
if ((name != null) && (name.length() > 0)) {
channel.setDevice(name);
}
//int grabWidthBytes = raw.getRowBytes();
dataRowBytes = raw.getRowBytes();
dataWidth = dataRowBytes / 4;
//System.out.println("row bytes " + raw.getRowBytes() + " " +
// (raw.getRowBytes() / 4));
//int extraBytes = dataRowBytes - requestWidth*4;
//int extraPixels = extraBytes / 4;
//int videoWidth = requestWidth + extraPixels;
dataHeight = raw.getSize() / dataRowBytes;
//System.out.println("height req, actual: " + requestHeight +
// " " + dataHeight);
if (dataWidth != requestWidth) {
crop = true;
cropX = 0;
cropY = 0;
cropW = requestWidth;
cropH = requestHeight;
/*
System.out.println("dataWidth is " + dataWidth +
" not " + requestWidth);
if (removeBorders) {
int bpixels[] = new int[dataWidth * requestHeight];
borderImage = new PImage(bpixels, dataWidth, requestHeight, RGB);
} else {
requestWidth = dataWidth;
}
*/
}
// initialize my PImage self
super.init(requestWidth, requestHeight, RGB);
@@ -229,19 +178,17 @@ public class Camera extends PImage implements Runnable {
new Class[] { Camera.class });
} catch (Exception e) {
// no such method, or an error.. which is fine, just ignore
//e.printStackTrace();
}
} catch (StdQTException qte) {
//qte.printStackTrace();
int errorCode = qte.errorCode();
// where's the friggin constant for this?
if (errorCode == -9405) {
if (errorCode == Errors.couldntGetRequiredComponent) {
// this can happen when the camera isn't available or
// wasn't shut down properly
parent.die("The camera (or VDIG) is not " +
"installed correctly (see readme.txt).", qte);
parent.die("No camera could be found, " +
"or the VDIG is not installed correctly.", qte);
} else {
parent.die("Error while setting up Camera", qte);
}
@@ -252,11 +199,20 @@ public class Camera extends PImage implements Runnable {
/**
* True if a frame is ready to be read. Example:
* True if a frame is ready to be read.
* <PRE>
* // put this somewhere inside draw
* if (camera.available()) camera.read();
* <P>
* </PRE>
* Alternatively, you can use cameraEvent(Camera c) to notify you
* whenever available() is set to true.
* whenever available() is set to true. In which case, things might
* look like this:
* <PRE>
* public void cameraEvent(Camera c) {
* c.read();
* // do something exciting now that c has been updated
* }
* </PRE>
*/
public boolean available() {
return available;
@@ -291,6 +247,13 @@ public class Camera extends PImage implements Runnable {
}
/**
* Remove the cropping (if any) of the image.
* <P>
* By default, cropping is often enabled to trim out black pixels.
* But if you'd rather deal with them yourself (so as to avoid
* an extra lag while the data is moved around) you can shut it off.
*/
public void noCrop() {
crop = false;
}
@@ -325,21 +288,7 @@ public class Camera extends PImage implements Runnable {
sourceOffset += dataWidth;
destOffset += width;
}
/*
if (borderImage != null) { // need to remove borders
raw.copyToArray(0, borderImage.pixels,
0, borderImage.width * borderImage.height);
int borderIndex = 0;
int targetIndex = 0;
for (int i = 0; i < height; i++) {
System.arraycopy(borderImage.pixels, borderIndex,
pixels, targetIndex, width);
borderIndex += borderImage.width;
targetIndex += width;
}
*/
} else { // just copy directly
} else { // no crop, just copy directly
raw.copyToArray(0, pixels, 0, width * height);
}
//long t2 = System.currentTimeMillis();
@@ -378,7 +327,7 @@ public class Camera extends PImage implements Runnable {
}
try {
Thread.sleep(1000 / fps);
Thread.sleep(1000 / framerate);
} catch (InterruptedException e) { }
}
}
@@ -388,13 +337,13 @@ public class Camera extends PImage implements Runnable {
* Set the framerate for how quickly new frames are read
* from the camera.
*/
public void framerate(int ifps) {
if (ifps <= 0) {
public void framerate(int iframerate) {
if (iframerate <= 0) {
System.err.println("Camera: ignoring bad framerate of " +
ifps + " fps.");
iframerate + " fps.");
return;
}
fps = ifps;
framerate = iframerate;
}
@@ -436,11 +385,78 @@ public class Camera extends PImage implements Runnable {
/**
* Shows the settings dialog for this channel.
* Set the format to ask for from the video digitizer:
* TUNER, COMPOSITE, SVIDEO, or COMPONENT.
* <P>
* The constants are just aliases to the constants returned from
* QuickTime's getInputFormat() function, so any valid constant from
* that will work just fine.
*/
//public void prompt() {
//channel.settingsDialog();
//}
public void source(int which) {
try {
VideoDigitizer digitizer = channel.getDigitizerComponent();
int count = digitizer.getNumberOfInputs();
for (int i = 0; i < count; i++) {
//System.out.println("format " + digitizer.getInputFormat(i));
if (digitizer.getInputFormat(i) == which) {
digitizer.setInput(i);
return;
}
}
throw new RuntimeException("The specified source() is not available.");
} catch (StdQTException e) {
e.printStackTrace();
throw new RuntimeException("Could not set the video input source.");
}
}
/**
* Set the video format standard to use on the
* video digitizer: NTSC, PAL, or SECAM.
* <P>
* The constants are just aliases to the constants used for
* QuickTime's setInputStandard() function, so any valid
* constant from that will work just fine.
*/
public void format(int which) {
try {
VideoDigitizer digitizer = channel.getDigitizerComponent();
digitizer.setInputStandard(which);
} catch (StdQTException e) {
e.printStackTrace();
//throw new RuntimeException("Could not set the video input format");
}
}
/**
* Show the settings dialog for this input device.
*/
public void settings() {
try {
channel.settingsDialog();
} catch (StdQTException qte) {
int errorCode = qte.errorCode();
if (errorCode != Errors.userCanceledErr) {
qte.printStackTrace();
throw new RuntimeException("error inside Camera.settings()");
}
}
}
/*
public String[] listInputs() {
VideoDigitizer digitizer = channel.getDigitizerComponent();
int count = digitizer.getNumberOfInputs();
String outgoing[] = new String[count];
//digitizer.setInput(2); // or something
//DigitizerInfo di = digitizer.getDigitizerInfo()
}
*/
/**