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 + -
显示快捷键?