Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

1199
LINES

< > BotCompany Repo | #1014901 // JavaX Live WebCam - Show live webcam image in frame v5 [try to minimize CPU when iconified - program works, but doesn't make a difference to vanilla WebcamPanel]

JavaX source code (desktop) [tags: use-pretranspiled] - run with: x30.jar

Download Jar. Uses 6490K of libraries. Click here for Pure Java version (10470L/73K).

!7

import static java.awt.RenderingHints.KEY_ANTIALIASING;
import static java.awt.RenderingHints.KEY_INTERPOLATION;
import static java.awt.RenderingHints.KEY_RENDERING;
import static java.awt.RenderingHints.VALUE_ANTIALIAS_OFF;
import static java.awt.RenderingHints.VALUE_ANTIALIAS_ON;
import static java.awt.RenderingHints.VALUE_INTERPOLATION_BILINEAR;
import static java.awt.RenderingHints.VALUE_RENDER_SPEED;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

static BufferedImage imageFromWebcamPanel(WebcamPanel2 panel) {
  ret panel.image;
}
/**
 * Simply implementation of JPanel allowing users to render pictures taken with webcam.
 *
 * @author Bartosz Firyn (SarXos)
 */
sclass WebcamPanel2 extends JPanel implements WebcamListener, PropertyChangeListener {

	/**
	 * This enum is to control of how image will be drawn in the panel bounds.
	 *
	 * @author Sylwia Kauczor
	 */
	public enum DrawMode {

		/**
		 * Do not resize image - paint it as it is. This will make the image to go off out the
		 * bounds if panel is smaller than image size.
		 */
		NONE,

		/**
		 * Will resize image to the panel bounds. This mode does not care of the image scale, so the
		 * final image may be disrupted.
		 */
		FILL,

		/**
		 * Will fir image into the panel bounds. This will resize the image and keep both x and y
		 * scale factor.
		 */
		FIT,
	}

	public interface ImageSupplier {
		public BufferedImage get();
	}

	private static class DefaultImageSupplier implements ImageSupplier {

		private final Webcam webcam;

		public DefaultImageSupplier(Webcam webcam) {
			this.webcam = webcam;
		}

		@Override
		public BufferedImage get() {
			return webcam.getImage();
		}
	}

	/**
	 * Interface of the painter used to draw image in panel.
	 *
	 * @author Bartosz Firyn (SarXos)
	 */
	public interface Painter {

		/**
		 * Paint panel without image.
		 *
		 * @param panel the webcam panel to paint on
		 * @param g2 the graphics 2D object used for drawing
		 */
		void paintPanel(WebcamPanel2 panel, Graphics2D g2);

		/**
		 * Paint webcam image in panel.
		 *
		 * @param panel the webcam panel to paint on
		 * @param image the image from webcam
		 * @param g2 the graphics 2D object used for drawing
		 */
		void paintImage(WebcamPanel2 panel, BufferedImage image, Graphics2D g2);
	}

	/**
	 * Default painter used to draw image in panel.
	 *
	 * @author Bartosz Firyn (SarXos)
	 * @author Sylwia Kauczor
	 */
	public class DefaultPainter implements Painter {

		/**
		 * Webcam device name.
		 */
		private String name = null;

		/**
		 * Lat repaint time, uset for debug purpose.
		 */
		private long lastRepaintTime = -1;

		/**
		 * Buffered image resized to fit into panel drawing area.
		 */
		private BufferedImage resizedImage = null;

		@Override
		public void paintPanel(WebcamPanel2 owner, Graphics2D g2) {

			assert owner != null;
			assert g2 != null;

			Object antialiasing = g2.getRenderingHint(KEY_ANTIALIASING);

			g2.setRenderingHint(KEY_ANTIALIASING, isAntialiasingEnabled() ? VALUE_ANTIALIAS_ON : VALUE_ANTIALIAS_OFF);
			g2.setBackground(Color.BLACK);
			g2.fillRect(0, 0, getWidth(), getHeight());

			int cx = (getWidth() - 70) / 2;
			int cy = (getHeight() - 40) / 2;

			g2.setStroke(new BasicStroke(2));
			g2.setColor(Color.LIGHT_GRAY);
			g2.fillRoundRect(cx, cy, 70, 40, 10, 10);
			g2.setColor(Color.WHITE);
			g2.fillOval(cx + 5, cy + 5, 30, 30);
			g2.setColor(Color.LIGHT_GRAY);
			g2.fillOval(cx + 10, cy + 10, 20, 20);
			g2.setColor(Color.WHITE);
			g2.fillOval(cx + 12, cy + 12, 16, 16);
			g2.fillRoundRect(cx + 50, cy + 5, 15, 10, 5, 5);
			g2.fillRect(cx + 63, cy + 25, 7, 2);
			g2.fillRect(cx + 63, cy + 28, 7, 2);
			g2.fillRect(cx + 63, cy + 31, 7, 2);

			g2.setColor(Color.DARK_GRAY);
			g2.setStroke(new BasicStroke(3));
			g2.drawLine(0, 0, getWidth(), getHeight());
			g2.drawLine(0, getHeight(), getWidth(), 0);

			String str;

			final String strInitDevice = rb.getString("INITIALIZING_DEVICE");
			final String strNoImage = rb.getString("NO_IMAGE");
			final String strDeviceError = rb.getString("DEVICE_ERROR");

			if (errored) {
				str = strDeviceError;
			} else {
				str = starting ? strInitDevice : strNoImage;
			}

			FontMetrics metrics = g2.getFontMetrics(getFont());
			int w = metrics.stringWidth(str);
			int h = metrics.getHeight();

			int x = (getWidth() - w) / 2;
			int y = cy - h;

			g2.setFont(getFont());
			g2.setColor(Color.WHITE);
			g2.drawString(str, x, y);

			if (name == null) {
				name = webcam.getName();
			}

			str = name;

			w = metrics.stringWidth(str);
			h = metrics.getHeight();

			g2.drawString(str, (getWidth() - w) / 2, cy - 2 * h);
			g2.setRenderingHint(KEY_ANTIALIASING, antialiasing);
		}

		@Override
		public void paintImage(WebcamPanel2 owner, BufferedImage image, Graphics2D g2) {

			assert owner != null;
			assert image != null;
			assert g2 != null;

			int pw = getWidth();
			int ph = getHeight();
			int iw = image.getWidth();
			int ih = image.getHeight();

			Object antialiasing = g2.getRenderingHint(KEY_ANTIALIASING);
			Object rendering = g2.getRenderingHint(KEY_RENDERING);

			g2.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_OFF);
			g2.setRenderingHint(KEY_RENDERING, VALUE_RENDER_SPEED);
			g2.setBackground(Color.BLACK);
			g2.setColor(Color.BLACK);
			g2.fillRect(0, 0, pw, ph);

			// resized image position and size
			int x = 0;
			int y = 0;
			int w = 0;
			int h = 0;

			switch (drawMode) {
				case NONE:
					w = image.getWidth();
					h = image.getHeight();
					break;
				case FILL:
					w = pw;
					h = ph;
					break;
				case FIT:
					double s = Math.max((double) iw / pw, (double) ih / ph);
					double niw = iw / s;
					double nih = ih / s;
					double dx = (pw - niw) / 2;
					double dy = (ph - nih) / 2;
					w = (int) niw;
					h = (int) nih;
					x = (int) dx;
					y = (int) dy;
					break;
			}

			if (resizedImage != null) {
				resizedImage.flush();
			}

			if (w == image.getWidth() && h == image.getHeight() && !mirrored) {
				resizedImage = image;
			} else {

				GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment();
				GraphicsConfiguration gc = genv.getDefaultScreenDevice().getDefaultConfiguration();

				Graphics2D gr = null;
				try {

					resizedImage = gc.createCompatibleImage(pw, ph);
					gr = resizedImage.createGraphics();
					gr.setComposite(AlphaComposite.Src);

					for (Map.Entry<RenderingHints.Key, Object> hint : imageRenderingHints.entrySet()) {
						gr.setRenderingHint(hint.getKey(), hint.getValue());
					}

					gr.setBackground(Color.BLACK);
					gr.setColor(Color.BLACK);
					gr.fillRect(0, 0, pw, ph);

					int sx1, sx2, sy1, sy2; // source rectangle coordinates
					int dx1, dx2, dy1, dy2; // destination rectangle coordinates

					dx1 = x;
					dy1 = y;
					dx2 = x + w;
					dy2 = y + h;

					if (mirrored) {
						sx1 = iw;
						sy1 = 0;
						sx2 = 0;
						sy2 = ih;
					} else {
						sx1 = 0;
						sy1 = 0;
						sx2 = iw;
						sy2 = ih;
					}

					gr.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);

				} finally {
					if (gr != null) {
						gr.dispose();
					}
				}
			}

			g2.drawImage(resizedImage, 0, 0, null);

			if (isFPSDisplayed()) {

				String str = String.format("FPS: %.1f", webcam.getFPS());

				int sx = 5;
				int sy = ph - 5;

				g2.setFont(getFont());
				g2.setColor(Color.BLACK);
				g2.drawString(str, sx + 1, sy + 1);
				g2.setColor(Color.WHITE);
				g2.drawString(str, sx, sy);
			}

			if (isImageSizeDisplayed()) {

				String res = String.format("%d\u2A2F%d px", iw, ih);

				FontMetrics metrics = g2.getFontMetrics(getFont());
				int sw = metrics.stringWidth(res);
				int sx = pw - sw - 5;
				int sy = ph - 5;

				g2.setFont(getFont());
				g2.setColor(Color.BLACK);
				g2.drawString(res, sx + 1, sy + 1);
				g2.setColor(Color.WHITE);
				g2.drawString(res, sx, sy);
			}

			if (isDisplayDebugInfo()) {

				if (lastRepaintTime < 0) {
					lastRepaintTime = System.currentTimeMillis();
				} else {

					long now = System.currentTimeMillis();
					String res = String.format("DEBUG: repaints per second: %.1f", (double) 1000 / (now - lastRepaintTime));
					lastRepaintTime = now;
					g2.setFont(getFont());
					g2.setColor(Color.BLACK);
					g2.drawString(res, 6, 16);
					g2.setColor(Color.WHITE);
					g2.drawString(res, 5, 15);
				}
			}

			g2.setRenderingHint(KEY_ANTIALIASING, antialiasing);
			g2.setRenderingHint(KEY_RENDERING, rendering);
		}
	}

	private static final class PanelThreadFactory implements ThreadFactory {

		private static final AtomicInteger number = new AtomicInteger(0);

		@Override
		public Thread newThread(Runnable r) {
			Thread t = new Thread(r, String.format("webcam-panel-scheduled-executor-%d", number.incrementAndGet()));
			t.setUncaughtExceptionHandler(WebcamExceptionHandler.getInstance());
			t.setDaemon(true);
			return t;
		}
	}

	/**
	 * This runnable will do nothing more than repaint panel.
	 */
	private static final class SwingRepainter implements Runnable {

		private WebcamPanel2 panel = null;

		public SwingRepainter(WebcamPanel2 panel) {
			this.panel = panel;
		}

		@Override
		public void run() {
			panel.repaint();
		}
	}

	private static final long serialVersionUID = 1L;

	private static final Logger LOG = LoggerFactory.getLogger(WebcamPanel2.class);

	public static final double MIN_FREQUENCY = 0.016; // 1 frame per minute

	private static final double MAX_FREQUENCY = 50; // 50 frames per second

	private static final ThreadFactory THREAD_FACTORY = new PanelThreadFactory();

	public static final Map<RenderingHints.Key, Object> DEFAULT_IMAGE_RENDERING_HINTS = new HashMap<RenderingHints.Key, Object>();
	static {
		DEFAULT_IMAGE_RENDERING_HINTS.put(KEY_INTERPOLATION, VALUE_INTERPOLATION_BILINEAR);
		DEFAULT_IMAGE_RENDERING_HINTS.put(KEY_RENDERING, VALUE_RENDER_SPEED);
		DEFAULT_IMAGE_RENDERING_HINTS.put(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
	}

	/**
	 * This runnable will do nothing more than repaint panel.
	 */
	private final Runnable repaint = new SwingRepainter(this);

	/**
	 * Rendering hints to be used when painting image to be displayed.
	 */
	private Map<RenderingHints.Key, Object> imageRenderingHints = new HashMap<RenderingHints.Key, Object>(DEFAULT_IMAGE_RENDERING_HINTS);

	/**
	 * Scheduled executor acting as timer.
	 */
	private ScheduledExecutorService executor = null;

	/**
	 * Image updater reads images from camera and force panel to be repainted.
	 *
	 * @author Bartosz Firyn (SarXos)
	 */
	private class ImageUpdater implements Runnable {
		private class RepaintScheduler extends Thread {
			public RepaintScheduler() {
				setUncaughtExceptionHandler(WebcamExceptionHandler.getInstance());
				setName(String.format("repaint-scheduler-%s", webcam.getName()));
				setDaemon(true);
			}

			@Override
			public void run() {

				// do nothing when not running
				if (!running.get() || isInIconifiedFrame(WebcamPanel2.this)) {
				  _sleep(100);
					return;
				}

				repaintPanel();

				// loop when starting, to wait for images
				while (starting) {
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						throw new RuntimeException(e);
					}
				}

				// schedule update when webcam is open, otherwise schedule
				// second scheduler execution

				try {

					// FPS limit means that panel rendering frequency is
					// limited to the specific value and panel will not be
					// rendered more often then specific value

					if (webcam.isOpen()) {

						// TODO: rename FPS value in panel to rendering
						// frequency

						if (isFPSLimited()) {
							executor.scheduleAtFixedRate(updater, 0, (long) (1000 / frequency), TimeUnit.MILLISECONDS);
						} else {
							executor.scheduleWithFixedDelay(updater, 100, 1, TimeUnit.MILLISECONDS);
						}
					} else {
						executor.schedule(this, 500, TimeUnit.MILLISECONDS);
					}
				} catch (RejectedExecutionException e) {

					// executor has been shut down, which means that someone
					// stopped panel / webcam device before it was actually
					// completely started (it was in "starting" timeframe)

					LOG.warn("Executor rejected paint update");
					LOG.trace("Executor rejected paint update because of", e);
				}
			}
		}

		/**
		 * Update scheduler thread.
		 */
		private Thread scheduler = null;

		/**
		 * Is repainter running?
		 */
		private AtomicBoolean running = new AtomicBoolean(false);

		/**
		 * Start repainter. Can be invoked many times, but only first call will take effect.
		 */
		public void start() {
			if (running.compareAndSet(false, true)) {
				executor = Executors.newScheduledThreadPool(1, THREAD_FACTORY);
				scheduler = new RepaintScheduler();
				scheduler.start();
			}
		}

		/**
		 * Stop repainter. Can be invoked many times, but only first call will take effect.
		 *
		 * @throws InterruptedException
		 */
		public void stop() throws InterruptedException {
			if (running.compareAndSet(true, false)) {
				executor.shutdown();
				executor.awaitTermination(5000, TimeUnit.MILLISECONDS);
				scheduler.join();
			}
		}

		@Override
		public void run() {
			try {
				update();
			} catch (Throwable t) {
				errored = true;
				WebcamExceptionHandler.handle(t);
			}
		}

		/**
		 * Perform single panel area update (repaint newly obtained image).
		 */
		private void update() {

			// do nothing when updater not running, when webcam is closed, or
			// panel repainting is paused

			if (!running.get() || !webcam.isOpen() || paused) {
				return;
			}

			// get new image from webcam

			BufferedImage tmp = supplier.get();
			boolean repaint = true;

			if (tmp != null) {

				// ignore repaint if image is the same as before
				if (image == tmp) {
					repaint = false;
				}

				errored = false;
				image = tmp;
			}

			if (repaint) {
				repaintPanel();
			}
		}
	}

	/**
	 * Resource bundle.
	 */
	private ResourceBundle rb = null;

	/**
	 * The mode of how the image will be resized to fit into panel bounds. Default is
	 * {@link DrawMode#FIT}
	 *
	 * @see DrawMode
	 */
	private DrawMode drawMode = DrawMode.FIT;

	/**
	 * Frames requesting frequency.
	 */
	private double frequency = 5; // FPS

	/**
	 * Is frames requesting frequency limited? If true, images will be fetched in configured time
	 * intervals. If false, images will be fetched as fast as camera can serve them.
	 */
	private boolean frequencyLimit = false;

	/**
	 * Display FPS.
	 */
	private boolean frequencyDisplayed = false;

	/**
	 * Display image size.
	 */
	private boolean imageSizeDisplayed = false;

	/**
	 * Is antialiasing enabled (true by default).
	 */
	private boolean antialiasingEnabled = true;

	/**
	 * Webcam object used to fetch images.
	 */
	private final Webcam webcam;

	private final ImageSupplier supplier;

	/**
	 * Repainter is used to fetch images from camera and force panel repaint when image is ready.
	 */
	private final ImageUpdater updater;

	/**
	 * Image currently being displayed.
	 */
	BufferedImage image = null;

	/**
	 * Webcam is currently starting.
	 */
	private volatile boolean starting = false;

	/**
	 * Painting is paused.
	 */
	private volatile boolean paused = false;

	/**
	 * Is there any problem with webcam?
	 */
	private volatile boolean errored = false;

	/**
	 * Webcam has been started.
	 */
	private final AtomicBoolean started = new AtomicBoolean(false);

	/**
	 * Default painter.
	 */
	private final Painter defaultPainter = new DefaultPainter();

	/**
	 * Painter used to draw image in panel.
	 *
	 * @see #setPainter(Painter)
	 * @see #getPainter()
	 */
	private Painter painter = defaultPainter;

	/**
	 * Preferred panel size.
	 */
	private Dimension defaultSize = null;

	/**
	 * If debug info should be displayed.
	 */
	private boolean displayDebugInfo = false;

	/**
	 * Is image mirrored.
	 */
	private boolean mirrored = false;

	/**
	 * Creates webcam panel and automatically start webcam.
	 *
	 * @param webcam the webcam to be used to fetch images
	 */
	public WebcamPanel2(Webcam webcam) {
		this(webcam, true);
	}

	/**
	 * Creates new webcam panel which display image from camera in you your Swing application.
	 *
	 * @param webcam the webcam to be used to fetch images
	 * @param start true if webcam shall be automatically started
	 */
	public WebcamPanel2(Webcam webcam, boolean start) {
		this(webcam, null, start);
	}

	/**
	 * Creates new webcam panel which display image from camera in you your Swing application. If
	 * panel size argument is null, then image size will be used. If you would like to fill panel
	 * area with image even if its size is different, then you can use
	 * {@link WebcamPanel#setFillArea(boolean)} method to configure this.
	 *
	 * @param webcam the webcam to be used to fetch images
	 * @param size the size of panel
	 * @param start true if webcam shall be automatically started
	 * @see WebcamPanel#setFillArea(boolean)
	 */
	public WebcamPanel2(Webcam webcam, Dimension size, boolean start) {
		this(webcam, size, start, new DefaultImageSupplier(webcam));
	}

	public WebcamPanel2(Webcam webcam, Dimension size, boolean start, ImageSupplier supplier) {

		if (webcam == null) {
			throw new IllegalArgumentException(String.format("Webcam argument in %s constructor cannot be null!", getClass().getSimpleName()));
		}

		this.defaultSize = size;
		this.webcam = webcam;
		this.updater = new ImageUpdater();
		this.supplier = supplier;
		this.rb = WebcamUtils.loadRB(WebcamPanel.class, getLocale());

		setDoubleBuffered(true);

		addPropertyChangeListener("locale", this);

		if (size == null) {
			Dimension r = webcam.getViewSize();
			if (r == null) {
				r = webcam.getViewSizes()[0];
			}
			setPreferredSize(r);
		} else {
			setPreferredSize(size);
		}

		if (start) {
			start();
		}
	}

	/**
	 * Set new painter. Painter is a class which pains image visible when
	 *
	 * @param painter the painter object to be set
	 */
	public void setPainter(Painter painter) {
		this.painter = painter;
	}

	/**
	 * Get painter used to draw image in webcam panel.
	 *
	 * @return Painter object
	 */
	public Painter getPainter() {
		return painter;
	}

	@Override
	protected void paintComponent(Graphics g) {

		super.paintComponent(g);

		if (image == null) {
			painter.paintPanel(this, (Graphics2D) g);
		} else {
			painter.paintImage(this, image, (Graphics2D) g);
		}
	}

	/**
	 * Open webcam and start rendering.
	 */
	public void start() {

		if (!started.compareAndSet(false, true)) {
			return;
		}

		webcam.addWebcamListener(this);

		LOG.debug("Starting panel rendering and trying to open attached webcam");

		updater.start();

		starting = true;

		final SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {

			@Override
			protected Void doInBackground() throws Exception {

				try {
					if (!webcam.isOpen()) {
						errored = !webcam.open();
					}
				} catch (WebcamException e) {
					errored = true;
					throw e;
				} finally {
					starting = false;
					repaintPanel();
				}

				return null;
			}
		};
		worker.execute();
	}

	/**
	 * Stop rendering and close webcam.
	 */
	public void stop() {

		if (!started.compareAndSet(true, false)) {
			return;
		}

		webcam.removeWebcamListener(this);

		LOG.debug("Stopping panel rendering and closing attached webcam");

		try {
			updater.stop();
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}

		image = null;

		final SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {

			@Override
			protected Void doInBackground() throws Exception {

				try {
					if (webcam.isOpen()) {
						errored = !webcam.close();
					}
				} catch (WebcamException e) {
					errored = true;
					throw e;
				} finally {
					repaintPanel();
				}

				return null;
			}
		};
		worker.execute();
	}

	/**
	 * Repaint panel in Swing asynchronous manner.
	 */
	private void repaintPanel() {
		SwingUtilities.invokeLater(repaint);
	}

	/**
	 * Pause rendering.
	 */
	public void pause() {
		if (paused) {
			return;
		}

		LOG.debug("Pausing panel rendering");

		paused = true;
	}

	/**
	 * Resume rendering.
	 */
	public void resume() {

		if (!paused) {
			return;
		}

		LOG.debug("Resuming panel rendering");

		paused = false;
	}

	/**
	 * Is frequency limit enabled?
	 *
	 * @return True or false
	 */
	public boolean isFPSLimited() {
		return frequencyLimit;
	}

	/**
	 * Enable or disable frequency limit. Frequency limit should be used for <b>all IP cameras
	 * working in pull mode</b> (to save number of HTTP requests). If true, images will be fetched
	 * in configured time intervals. If false, images will be fetched as fast as camera can serve
	 * them.
	 *
	 * @param frequencyLimit true if limiting the frequency of image requests
	 */
	public void setFPSLimited(boolean frequencyLimit) {
		this.frequencyLimit = frequencyLimit;
	}

	/**
	 * Get rendering frequency in FPS (equivalent to Hz).
	 *
	 * @return Rendering frequency
	 */
	public double getFPSLimit() {
		return frequency;
	}

	/**
	 * Set rendering frequency (in Hz or FPS). Minimum frequency is 0.016 (1 frame per minute) and
	 * maximum is 25 (25 frames per second).
	 *
	 * @param fps the frequency
	 */
	public void setFPSLimit(double fps) {
		if (fps > MAX_FREQUENCY) {
			fps = MAX_FREQUENCY;
		}
		if (fps < MIN_FREQUENCY) {
			fps = MIN_FREQUENCY;
		}
		this.frequency = fps;
	}

	/**
	 * Is displaying of some debug information enabled.
	 *
	 * @return True if debug information are enabled, false otherwise
	 */
	public boolean isDisplayDebugInfo() {
		return displayDebugInfo;
	}

	/**
	 * Display some debug information on image surface.
	 *
	 * @param displayDebugInfo the value to control debug information
	 */
	public void setDisplayDebugInfo(boolean displayDebugInfo) {
		this.displayDebugInfo = displayDebugInfo;
	}

	/**
	 * This method return true in case if camera FPS is set to be displayed on panel surface.
	 * Default value returned is false.
	 *
	 * @return True if camera FPS is set to be displayed on panel surface
	 * @see #setFPSDisplayed(boolean)
	 */
	public boolean isFPSDisplayed() {
		return frequencyDisplayed;
	}

	/**
	 * This method is to control if camera FPS should be displayed on the webcam panel surface.
	 *
	 * @param displayed the value to control if camera FPS should be displayed
	 */
	public void setFPSDisplayed(boolean displayed) {
		this.frequencyDisplayed = displayed;
	}

	/**
	 * This method will return true in case when panel is configured to display image size. The
	 * string will be printed in the right bottom corner of the panel surface.
	 *
	 * @return True in case if panel is configured to display image size
	 */
	public boolean isImageSizeDisplayed() {
		return imageSizeDisplayed;
	}

	/**
	 * Configure panel to display camera image size to be displayed.
	 *
	 * @param imageSizeDisplayed if true the pixel dimensions are displayed over the image.
	 */
	public void setImageSizeDisplayed(boolean imageSizeDisplayed) {
		this.imageSizeDisplayed = imageSizeDisplayed;
	}

	/**
	 * Turn on/off antialiasing.
	 *
	 * @param antialiasing the true to enable, false to disable antialiasing
	 */
	public void setAntialiasingEnabled(boolean antialiasing) {
		this.antialiasingEnabled = antialiasing;
	}

	/**
	 * @return True is antialiasing is enabled, false otherwise
	 */
	public boolean isAntialiasingEnabled() {
		return antialiasingEnabled;
	}

	/**
	 * Is webcam panel repainting starting.
	 *
	 * @return True if panel is starting
	 */
	public boolean isStarting() {
		return starting;
	}

	/**
	 * Is webcam panel repainting started.
	 *
	 * @return True if panel repainting has been started
	 */
	public boolean isStarted() {
		return started.get();
	}

	/**
	 * This method returns the current draw mode, mainly used by custom painters
	 * 
	 * @return the current value of the {@link DrawMode}
	 */
	public DrawMode getDrawMode() {
		return this.drawMode;
	}

	/**
	 * This method sets the drawmode
	 * 
	 * @param drawMode the desired {@link DrawMode}
	 */
	public void setDrawMode(DrawMode drawMode) {
		this.drawMode = drawMode;
	}

	/**
	 * Indicates whether the panel is in an error state
	 * 
	 * @return true if the panel has an error present
	 */
	public boolean isErrored() {
		return errored;
	}

	/**
	 * Hints for rendering, mainly used for custom painters
	 * 
	 * @return the stored RenderingHints
	 * @deprecated use {@link #getDrawMode()} instead.
	 */
	@Deprecated
	public Map<RenderingHints.Key, Object> getImageRenderingHints() {
		return imageRenderingHints;
	}

	@Deprecated
	public boolean isFitArea() {
		return drawMode == DrawMode.FIT;
	}

	/**
	 * This method will change the mode of panel area painting so the image will be resized and will
	 * keep scale factor to fit into drawable panel bounds. When set to false, the mode will be
	 * reset to {@link DrawMode#NONE} so image will be drawn as it is.
	 *
	 * @param fitArea the fit area mode enabled or disabled
	 * @deprecated use {@link #setDrawMode(DrawMode drawMode)} instead.
	 */
	@Deprecated
	public void setFitArea(boolean fitArea) {
		this.drawMode = fitArea ? DrawMode.FIT : DrawMode.NONE;
	}

	/**
	 * Image will be resized to fill panel area if true. If false then image will be rendered as it
	 * was obtained from webcam instance.
	 *
	 * @param fillArea shall image be resided to fill panel area
	 * @deprecated use {@link #setDrawMode(DrawMode drawMode)} instead.
	 */
	@Deprecated
	public void setFillArea(boolean fillArea) {
		this.drawMode = fillArea ? DrawMode.FILL : DrawMode.NONE;
	}

	/**
	 * Get value of fill area setting. Image will be resized to fill panel area if true. If false
	 * then image will be rendered as it was obtained from webcam instance.
	 *
	 * @return True if image is being resized, false otherwise
	 * @deprecated use {@link #getDrawMode()} instead.
	 */
	@Deprecated
	public boolean isFillArea() {
		return drawMode == DrawMode.FILL;
	}

	/**
	 * Get default painter used to draw panel.
	 *
	 * @return Default painter
	 */
	public Painter getDefaultPainter() {
		return defaultPainter;
	}

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		Locale lc = (Locale) evt.getNewValue();
		if (lc != null) {
			rb = WebcamUtils.loadRB(WebcamPanel.class, lc);
		}
	}

	@Override
	public void webcamOpen(WebcamEvent we) {

		// if default size has not been provided, then use the one from webcam
		// device (this will be current webcam resolution)

		if (defaultSize == null) {
			setPreferredSize(webcam.getViewSize());
		}
	}

	@Override
	public void webcamClosed(WebcamEvent we) {
		stop();
	}

	@Override
	public void webcamDisposed(WebcamEvent we) {
		stop();
	}

	@Override
	public void webcamImageObtained(WebcamEvent we) {
		// do nothing
	}

	/**
	 * This method returns true if image mirroring is enabled. The default value is false.
	 *
	 * @return True if image is mirrored, false otherwise
	 */
	public boolean isMirrored() {
		return mirrored;
	}

	/**
	 * Decide whether or not the image from webcam painted on panel surface will be mirrored. The
	 * image from camera itself is not modified.
	 *
	 * @param mirrored the parameter to control if image should be mirrored
	 */
	public void setMirrored(boolean mirrored) {
		this.mirrored = mirrored;
	}

	/**
	 * Return {@link Webcam} used by this panel.
	 * 
	 * @return {@link Webcam}
	 */
	public Webcam getWebcam() {
		return webcam;
	}

	/**
	 * @return {@link BufferedImage} displayed on {@link WebcamPanel}
	 */
	public BufferedImage getImage() {
		return image;
	}
}

static WebcamPanel2 panel;
static bool savingOn = true;
static double saveEvery = 10.0;
static volatile File latestSaved;

p {
  restartWith128MBHeap();
  outBuf(50000);
  substance();
  selectWebCam(voidfunc(Webcam cam) {
    panel = new WebcamPanel2(cam, true);
    panel.setFPSDisplayed(true);
    frameIcon(#1009177, exitProgramOnFrameClose(alwaysOnTop(showPackedFrame("JavaX Live WebCam", panel)));
    bot("WebCam.");
    doEvery_daemon_now(saveEvery, f saveDefault);
  });
  hideConsole();
}

answer {
  if "save jpeg at *" {
    saveJPEG(newFile($1), imageFromWebcamPanel(panel));
    ret "OK";
  }
  if "latest file"
    ret latestSaved == null ? "Not saved yet"
      : "OK " + quote(f2s(latestSaved));
}

svoid saveDefault {
  if (!savingOn) ret;
  File file = newFile(javaxDataDir(), "WebCam", ("webcam-" + dateWithSecondsForFile() + ".jpg");
  saveJPEG(file, imageFromWebcamPanel(panel));
  latestSaved = file;
}

Author comment

Began life as a copy of #1013489

download  show line numbers  debug dex  old transpilations   

Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1014901
Snippet name: JavaX Live WebCam - Show live webcam image in frame v5 [try to minimize CPU when iconified - program works, but doesn't make a difference to vanilla WebcamPanel]
Eternal ID of this version: #1014901/8
Text MD5: 7750d67fc344e1dcaecf6d54d46f14bb
Transpilation MD5: 6c38f054e53b86af88e25be20646b691
Author: stefan
Category: javax / desktop / camera
Type: JavaX source code (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2018-05-06 11:38:19
Source code size: 29723 bytes / 1199 lines
Pitched / IR pitched: No / No
Views / Downloads: 284 / 755
Version history: 7 change(s)
Referenced in: [show references]