capture.java
来自「This is processing for java examples.」· Java 代码 · 共 548 行 · 第 1/2 页
JAVA
548 行
* of an image, so this can be useful for removing them. * Internally, the pixel buffer size returned from QuickTime is * often a different size than requested, so crop will be set * more often than not. */ public void crop(int x, int y, int w, int h) { /* if (imageMode == CORNERS) { w -= x; // w was actually x2 h -= y; // h was actually y2 } */ crop = true; cropX = Math.max(0, x); cropY = Math.max(0, y); cropW = Math.min(w, dataWidth); cropH = Math.min(dataHeight, y + h) - cropY; // if size has changed, re-init this image if ((cropW != width) || (cropH != height)) { init(w, h, RGB); } } /** * 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; } public void read() { //try { //synchronized (capture) { loadPixels(); synchronized (pixels) { //System.out.println("read1"); if (crop) { //System.out.println("read2a"); // f#$)(#$ing quicktime / jni is so g-d slow, calling copyToArray // for the invidual rows is literally 100x slower. instead, first // copy the entire buffer to a separate array (i didn't need that // memory anyway), and do an arraycopy for each row. if (data == null) { data = new int[dataWidth * dataHeight]; } raw.copyToArray(0, data, 0, dataWidth * dataHeight); int sourceOffset = cropX + cropY*dataWidth; int destOffset = 0; for (int y = 0; y < cropH; y++) { System.arraycopy(data, sourceOffset, pixels, destOffset, cropW); sourceOffset += dataWidth; destOffset += width; } } else { // no crop, just copy directly //System.out.println("read2b"); raw.copyToArray(0, pixels, 0, width * height); } //System.out.println("read3"); available = false; // mark this image as modified so that PGraphicsJava2D and // PGraphicsOpenGL will properly re-blit and draw this guy updatePixels(); //System.out.println("read4"); } } public void run() { while ((Thread.currentThread() == runner) && (capture != null)) { try { synchronized (capture) { capture.idle(); //read(); available = true; if (captureEventMethod != null) { try { captureEventMethod.invoke(parent, new Object[] { this }); } catch (Exception e) { System.err.println("Disabling captureEvent() for " + name + " because of an error."); e.printStackTrace(); captureEventMethod = null; } } } } catch (QTException e) { errorMessage("run", e); } try { Thread.sleep(1000 / frameRate); } catch (InterruptedException e) { } } } /** * Set the frameRate for how quickly new frames are read * from the capture device. */ public void frameRate(int iframeRate) { if (iframeRate <= 0) { System.err.println("Capture: ignoring bad frameRate of " + iframeRate + " fps."); return; } frameRate = iframeRate; } /** * Called by applets to stop capturing video. */ public void stop() { if (capture != null) { try { capture.stop(); // stop the "preview" } catch (StdQTException e) { e.printStackTrace(); } capture = null; } runner = null; // unwind the thread } /** * Called by PApplet to shut down video so that QuickTime * can be used later by another applet. */ public void dispose() { stop(); //System.out.println("calling dispose"); // this is important so that the next app can do video QTSession.close(); } /** * General error reporting, all corraled here just in case * I think of something slightly more intelligent to do. */ protected void errorMessage(String where, Exception e) { parent.die("Error inside Capture." + where + "()", e); } /** * 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 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 { // fix for crash here submitted by hansi (stop/startPreview lines) capture.stop(); // Whenever settingsDialog() is called, the boundries change, // causing the image to be cropped. Fix for Bug #366 // http://dev.processing.org/bugs/show_bug.cgi?id=366 channel.setBounds(qdrect); // Open the settings dialog (throws an Exception if canceled) channel.settingsDialog(); } catch (StdQTException qte) { int errorCode = qte.errorCode(); if (errorCode == Errors.userCanceledErr) { // User only canceled the settings dialog, continue as we were } else { qte.printStackTrace(); throw new RuntimeException("Error inside Capture.settings()"); } } try { // Start the preview again (unreachable if newly thrown exception) capture.startPreview(); } catch (StdQTException qte) { qte.printStackTrace(); } } /** * Get a list of all available captures as a String array. * i.e. println(Capture.list()) will show you the goodies. */ static public String[] list() { try { QTSession.open(); SequenceGrabber grabber = new SequenceGrabber(); SGVideoChannel channel = new SGVideoChannel(grabber); SGDeviceList deviceList = channel.getDeviceList(0); // flags is 0 String listing[] = new String[deviceList.getCount()]; for (int i = 0; i < deviceList.getCount(); i++) { listing[i] = deviceList.getDeviceName(i).getName(); } // properly shut down the channel so the app can use it again grabber.disposeChannel(channel); QTSession.close(); return listing; } catch (QTException qte) { int errorCode = qte.errorCode(); if (errorCode == Errors.couldntGetRequiredComponent) { throw new RuntimeException("Couldn't find any capture devices, " + "read the video reference for more info."); } else { qte.printStackTrace(); throw new RuntimeException("Problem listing capture devices, " + "read the video reference for more info."); } } //return null; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?