Skip to content
Snippets Groups Projects
Commit edeedf3b authored by Richard Alam's avatar Richard Alam
Browse files

- add parameters to scale captured screen

parent f0246080
No related branches found
No related tags found
No related merge requests found
.classpath
.gradle/
.project
app/build/classes/
app/build/libs/
applet/build/classes/
applet/build/libs/
bin/
common/build/classes/
common/build/ivy.xml
common/build/libs/
lib/
libs
deskshare
......@@ -30,8 +30,11 @@ public class DeskShareApplet extends Applet implements ClientListener {
String hostValue = "localhost";
Integer portValue = new Integer(9123);
String roomValue = "85115";
Integer widthValue = new Integer(800);
Integer heightValue = new Integer(600);
Integer cWidthValue = new Integer(800);
Integer cHeightValue = new Integer(600);
Integer sWidthValue = new Integer(800);
Integer sHeightValue = new Integer(600);
Boolean qualityValue = false;
Integer xValue = new Integer(0);
Integer yValue = new Integer(0);
Boolean tunnelValue = true;
......@@ -43,10 +46,19 @@ public class DeskShareApplet extends Applet implements ClientListener {
String port = getParameter("PORT");
if (port != null) portValue = Integer.parseInt(port);
roomValue = getParameter("ROOM");
widthValue = Integer.parseInt(getParameter("CAPTURE_WIDTH"));
heightValue = Integer.parseInt(getParameter("CAPTURE_HEIGHT"));
cWidthValue = Integer.parseInt(getParameter("CAPTURE_WIDTH"));
cHeightValue = Integer.parseInt(getParameter("CAPTURE_HEIGHT"));
xValue = Integer.parseInt(getParameter("X"));
yValue = Integer.parseInt(getParameter("Y"));
String scaleWidth = getParameter("SCALE_WIDTH");
if (scaleWidth != null) sWidthValue = Integer.parseInt(scaleWidth);
String scaleHeight = getParameter("SCALE_HEIGHT");
if (scaleHeight != null) sHeightValue = Integer.parseInt(scaleHeight);
String qualityCapture = getParameter("SCALE_WITH_QUALITY");
if (qualityCapture != null) qualityValue = Boolean.parseBoolean(qualityCapture);
String tunnel = getParameter("HTTP_TUNNEL");
if (tunnel != null) tunnelValue = Boolean.parseBoolean(tunnel);
icon = getImage(getCodeBase(), "bbb.gif");
......@@ -55,9 +67,10 @@ public class DeskShareApplet extends Applet implements ClientListener {
public void start() {
System.out.println("Start");
client = new DeskshareClient.Builder().host(hostValue).port(portValue)
.room(roomValue).width(widthValue)
.height(heightValue).x(xValue).y(yValue)
.httpTunnel(tunnelValue).trayIcon(icon).enableTrayIconActions(false).build();
.room(roomValue).captureWidth(cWidthValue)
.captureHeight(cHeightValue).scaleWidth(sWidthValue).scaleHeight(sHeightValue).quality(qualityValue)
.x(xValue).y(yValue)
.httpTunnel(tunnelValue).trayIcon(icon).enableTrayIconActions(true).build();
client.start();
}
......
......@@ -40,8 +40,11 @@ class DeskshareClient implements IScreenCaptureListener, ChangedBlocksListener,
private String host;
private int port;
private String room;
private int width;
private int height;
private int captureWidth;
private int captureHeight;
private int scaleWidth;
private int scaleHeight;
private boolean quality;
private int x;
private int y;
private boolean httpTunnel;
......@@ -58,7 +61,8 @@ class DeskshareClient implements IScreenCaptureListener, ChangedBlocksListener,
System.out.println("Desktop Sharing v0.64");
System.out.println("Start");
System.out.println("Connecting to " + host + ":" + port + " room " + room);
System.out.println("Sharing " + width + "x" + height + " at " + x + "," + y);
System.out.println("Sharing " + captureWidth + "x" + captureHeight + " at " + x + "," + y);
System.out.println("Scale to " + scaleWidth + "x" + scaleHeight + " with quality = " + quality);
System.out.println("Http Tunnel: " + httpTunnel);
tray.addSystemTrayListener(this);
tray.displayIconOnSystemTray(sysTrayIcon, enableTrayActions);
......@@ -68,11 +72,11 @@ class DeskshareClient implements IScreenCaptureListener, ChangedBlocksListener,
}
private void startCapture() {
capture = new ScreenCapture(x, y, width, height);
capture = new ScreenCapture(x, y, captureWidth, captureHeight, scaleWidth, scaleHeight, quality);
captureTaker = new ScreenCaptureTaker(capture);
mTaker = new MouseLocationTaker();
Dimension screenDim = new Dimension(width, height);
Dimension screenDim = new Dimension(scaleWidth, scaleHeight);
Dimension tileDim = new Dimension(blockWidth, blockHeight);
blockManager = new BlockManager();
blockManager.addListener(this);
......@@ -163,8 +167,11 @@ class DeskshareClient implements IScreenCaptureListener, ChangedBlocksListener,
room = builder.room;
host = builder.host;
port = builder.port;
width = builder.width;
height = builder.height;
captureWidth = builder.captureWidth;
captureHeight = builder.captureHeight;
scaleWidth = builder.scaleWidth;
scaleHeight = builder.scaleHeight;
quality = builder.quality;
x = builder.x;
y = builder.y;
httpTunnel = builder.httpTunnel;
......@@ -181,8 +188,11 @@ class DeskshareClient implements IScreenCaptureListener, ChangedBlocksListener,
private String host;
private int port;
private String room;
private int width;
private int height;
private int captureWidth;
private int captureHeight;
private int scaleWidth;
private int scaleHeight;
private boolean quality;
private int x;
private int y;
private boolean httpTunnel;
......@@ -206,13 +216,28 @@ class DeskshareClient implements IScreenCaptureListener, ChangedBlocksListener,
return this;
}
public Builder width(int width) {
this.width = width;
public Builder captureWidth(int width) {
this.captureWidth = width;
return this;
}
public Builder height(int height) {
this.height = height;
public Builder captureHeight(int height) {
this.captureHeight = height;
return this;
}
public Builder scaleWidth(int width) {
this.scaleWidth = width;
return this;
}
public Builder scaleHeight(int height) {
this.scaleHeight = height;
return this;
}
public Builder quality(boolean quality) {
this.quality = quality;
return this;
}
......
......@@ -36,9 +36,11 @@ public class DeskshareMain implements ClientListener, LifeLineListener {
CmdLineParser.Option port = dsMain.addHelp(parser.addIntegerOption('p', "port"),"The port the application is listening");
CmdLineParser.Option listenPort = dsMain.addHelp(parser.addIntegerOption('l', "listenPort"),"Port to listen for lifeline");
CmdLineParser.Option room = dsMain.addHelp(parser.addStringOption('r', "room"),"Room");
CmdLineParser.Option width = dsMain.addHelp(parser.addIntegerOption('w', "width"),"Width of the screen capture");
CmdLineParser.Option height = dsMain.addHelp(parser.addIntegerOption('t', "height"),"Height of the screen capture");
CmdLineParser.Option xCoord = dsMain.addHelp(parser.addIntegerOption('x', "x"),"Upper-left x coordinate of the screen capture");
CmdLineParser.Option cWidth = dsMain.addHelp(parser.addIntegerOption('w', "captureWidth"),"Width of the screen capture");
CmdLineParser.Option cHeight = dsMain.addHelp(parser.addIntegerOption('t', "captureHeight"),"Height of the screen capture");
CmdLineParser.Option sWidth = dsMain.addHelp(parser.addIntegerOption('d', "scaleWidth"),"Scale capture width");
CmdLineParser.Option sHeight = dsMain.addHelp(parser.addIntegerOption('g', "scaleHeight"),"Scale capture height");
CmdLineParser.Option quality = dsMain.addHelp(parser.addBooleanOption('q', "quality"),"Scale with better quality instead of speed"); CmdLineParser.Option xCoord = dsMain.addHelp(parser.addIntegerOption('x', "x"),"Upper-left x coordinate of the screen capture");
CmdLineParser.Option yCoord = dsMain.addHelp(parser.addIntegerOption('y', "y"),"Upper-left y coordinate of the screen capture");
CmdLineParser.Option tryHttpTunnel = dsMain.addHelp(parser.addBooleanOption('n', "httptunnel"),"Http tunnel if direct connection fails");
CmdLineParser.Option icon = dsMain.addHelp(parser.addStringOption('i', "icon"),"Path to system tray icon file");
......@@ -66,8 +68,11 @@ public class DeskshareMain implements ClientListener, LifeLineListener {
Integer portValue = (Integer)parser.getOptionValue(port, new Integer(9123));
Integer listenPortValue = (Integer)parser.getOptionValue(listenPort, new Integer(9125));
String roomValue = (String)parser.getOptionValue(room, "85115");
Integer widthValue = (Integer)parser.getOptionValue(width, new Integer((int)dim.getWidth()));
Integer heightValue = (Integer)parser.getOptionValue(height, new Integer((int)dim.getHeight()));
Integer cWidthValue = (Integer)parser.getOptionValue(cWidth, new Integer((int)dim.getWidth()));
Integer cHeightValue = (Integer)parser.getOptionValue(cHeight, new Integer((int)dim.getHeight()));
Integer sWidthValue = (Integer)parser.getOptionValue(sWidth, new Integer((int)dim.getWidth()));
Integer sHeightValue = (Integer)parser.getOptionValue(sHeight, new Integer((int)dim.getHeight()));
Boolean qualityValue = (Boolean)parser.getOptionValue(quality, false);
Integer xValue = (Integer)parser.getOptionValue(xCoord, new Integer(0));
Integer yValue = (Integer)parser.getOptionValue(yCoord, new Integer(0));
Boolean tunnelValue = (Boolean)parser.getOptionValue(tryHttpTunnel, false);
......@@ -79,8 +84,9 @@ public class DeskshareMain implements ClientListener, LifeLineListener {
lifeline.listen();
DeskshareClient client = new DeskshareClient.Builder().host(hostValue).port(portValue)
.room(roomValue).width(widthValue)
.height(heightValue).x(xValue).y(yValue)
.room(roomValue).captureWidth(cWidthValue)
.captureHeight(cHeightValue).scaleWidth(sWidthValue).scaleHeight(sHeightValue).quality(qualityValue)
.x(xValue).y(yValue)
.httpTunnel(tunnelValue).trayIcon(image).enableTrayIconActions(true).build();
client.addClientListeners(dsMain);
......
......@@ -22,9 +22,16 @@
package org.bigbluebutton.deskshare.client;
import java.awt.AWTException;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
/**
......@@ -38,50 +45,39 @@ import java.awt.image.BufferedImage;
*/
public class ScreenCapture {
private Robot robot;
private Toolkit toolkit;
private Rectangle screenBounds;
private int width, height, x,y, videoWidth, videoHeight;
public ScreenCapture(int x, int y, int screenWidth, int screenHeight) {
this.width = screenWidth;
this.height = screenHeight;
private int scaleWidth, scaleHeight, x,y, captureWidth, captureHeight;
private boolean quality;
private GraphicsConfiguration jc;
public ScreenCapture(int x, int y, int captureWidth, int captureHeight, int scaleWidth, int scaleHeight, boolean quality) {
this.captureWidth = captureWidth;
this.captureHeight = captureHeight;
try{
robot = new Robot();
}catch (AWTException e){
System.out.println(e.getMessage());
}
this.toolkit = Toolkit.getDefaultToolkit();
this.screenBounds = new Rectangle(x, y, this.width, this.height);
this.screenBounds = new Rectangle(x, y, this.captureWidth, this.captureHeight);
this.scaleWidth = scaleWidth;
this.scaleHeight = scaleHeight;
this.quality = quality;
GraphicsEnvironment je = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice js = je.getDefaultScreenDevice();
jc = js.getDefaultConfiguration();
}
public BufferedImage takeSingleSnapshot() {
return robot.createScreenCapture(this.screenBounds);
}
public int getScreenshotWidth() {
return toolkit.getScreenSize().width;
}
public int getScreenshotHeight() {
return toolkit.getScreenSize().height;
}
public void setWidth(int width) {
int screenWidth = toolkit.getScreenSize().width;
if (width > screenWidth) this.width = screenWidth;
else this.width = width;
updateBounds();
}
public void setHeight(int height) {
int screenHeight = toolkit.getScreenSize().height;
if (height > screenHeight) {
this.height = screenHeight;
}
else {
this.height = height;
BufferedImage capturedImage = robot.createScreenCapture(this.screenBounds);
if (needToScaleImage()) {
if (quality) return useQuality(capturedImage);
return getScaledInstance(capturedImage, scaleWidth, scaleHeight, RenderingHints.VALUE_INTERPOLATION_BICUBIC, true);
} else {
return capturedImage;
}
updateBounds();
}
public void setX(int x) {
......@@ -95,32 +91,98 @@ public class ScreenCapture {
}
public void updateBounds() {
this.screenBounds = new Rectangle(x,y,width,height);
this.screenBounds = new Rectangle(x, y, captureWidth, captureHeight);
}
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
public int getProperFrameRate() {
long area = width*height;
if (area > 1000000) return 1;
else if (area > 600000) return 2;
else if (area > 300000) return 4;
else if (area > 150000) return 8;
else return 10;
}
public int getVideoWidth() {
return videoWidth;
}
public int getVideoHeight() {
return videoHeight;
}
private boolean needToScaleImage() {
return (captureWidth != scaleWidth && captureHeight != scaleHeight);
}
private BufferedImage useQuality(BufferedImage image) {
BufferedImage resultImage = jc.createCompatibleImage(scaleWidth, scaleHeight, image.getType());
resultImage.setAccelerationPriority(1);
Graphics2D g2 = resultImage.createGraphics();
Image scaledImage = image.getScaledInstance(scaleWidth, scaleHeight, Image.SCALE_AREA_AVERAGING);
g2.drawImage(scaledImage, 0, 0, scaleWidth, scaleHeight, null);
g2.dispose();
return resultImage;
}
/*
* GraphicsConfiguration GrphConfig = getGraphicsConfiguration();
BufferedImage offscreenBuf = GrphConfig.createCompatibleImage(bufWidth, bufHeight, Transparency.OPAQUE );
offscreenBuf.setAccelerationPriority(1);
*/
/**
* Convenience method that returns a scaled instance of the
* provided {@code BufferedImage}.
*
* @param img the original image to be scaled
* @param targetWidth the desired width of the scaled instance,
* in pixels
* @param targetHeight the desired height of the scaled instance,
* in pixels
* @param hint one of the rendering hints that corresponds to
* {@code RenderingHints.KEY_INTERPOLATION} (e.g.
* {@code RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR},
* {@code RenderingHints.VALUE_INTERPOLATION_BILINEAR},
* {@code RenderingHints.VALUE_INTERPOLATION_BICUBIC})
* @param higherQuality if true, this method will use a multi-step
* scaling technique that provides higher quality than the usual
* one-step technique (only useful in downscaling cases, where
* {@code targetWidth} or {@code targetHeight} is
* smaller than the original dimensions, and generally only when
* the {@code BILINEAR} hint is specified)
* @return a scaled version of the original {@code BufferedImage}
*/
public BufferedImage getScaledInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint,
boolean higherQuality)
{
int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage)img;
int w, h;
if (higherQuality) {
// Use multi-step technique: start with original size, then
// scale down in multiple passes with drawImage()
// until the target size is reached
w = img.getWidth();
h = img.getHeight();
} else {
// Use one-step technique: scale directly from original
// size to target size with a single drawImage() call
w = targetWidth;
h = targetHeight;
}
do {
if (higherQuality && w > targetWidth) {
w /= 2;
if (w < targetWidth) {
w = targetWidth;
}
}
if (higherQuality && h > targetHeight) {
h /= 2;
if (h < targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
} while (w != targetWidth || h != targetHeight);
return ret;
}
}
......@@ -36,7 +36,10 @@ public class ScreenCaptureTaker implements Runnable {
public void run(){
while (startCapture){
// System.out.println("----- Taking screen capture -----");
long start = System.currentTimeMillis();
BufferedImage image = capture.takeSingleSnapshot();
long end = System.currentTimeMillis();
System.out.println("Capture took " + (end - start) + " millis");
notifyListeners(image);
try{
Thread.sleep(200);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment