package org.openmeetings.client.util;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.zip.GZIPOutputStream;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;
import org.apache.log4j.Logger;
import org.openmeetings.client.beans.ClientConnectionBean;
import org.openmeetings.client.beans.ClientImageFrame;
import org.openmeetings.client.beans.ClientVirtualScreenBean;
//import com.sun.imageio.plugins.png.
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.imageio.plugins.gif.GIFImageWriter;
/**
* @author sebastianwagner
*
*/
public class ClientRaster {
private static Logger log = Logger.getLogger(ClientRaster.class);
public static synchronized List<ClientImageFrame> tileScreen() {
try {
List<ClientImageFrame> clientImageFrames = new LinkedList<ClientImageFrame>();
int tileNumberWidth = Double.valueOf(Math.floor(ClientVirtualScreenBean.vScreenSpinnerWidth / ClientConnectionBean.tileWidth)).intValue();
int tileNumberHeight = Double.valueOf(Math.floor(ClientVirtualScreenBean.vScreenSpinnerHeight / ClientConnectionBean.tileHeight)).intValue();
int xOffset = ClientVirtualScreenBean.vScreenSpinnerX;
int yOffset = ClientVirtualScreenBean.vScreenSpinnerY;
log.debug("ClientVirtualScreenBean.vScreenSpinnerWidth "+ClientVirtualScreenBean.vScreenSpinnerWidth);
log.debug("ClientConnectionBean.tileWidth "+ClientConnectionBean.tileWidth);
log.debug("ClientVirtualScreenBean.vScreenSpinnerWidth / ClientConnectionBean.tileWidth "+(ClientVirtualScreenBean.vScreenSpinnerWidth / ClientConnectionBean.tileWidth));
log.debug("ClientVirtualScreenBean.vScreenSpinnerHeight / ClientConnectionBean.tileHeight "+(ClientVirtualScreenBean.vScreenSpinnerHeight / ClientConnectionBean.tileHeight));
log.debug("tileNumberWidth,tileNumberHeight "+tileNumberWidth+","+tileNumberHeight);
log.debug("xOffset,yOffset "+xOffset+","+yOffset);
Robot robot = ClientVirtualScreenBean.robot;
if (robot==null) robot = new Robot();
Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
for (int x=0;x<=tileNumberWidth;x++) {
for (int y=0;y<=tileNumberHeight;y++) {
int rect_x = xOffset + ( x * ClientConnectionBean.tileWidth );
int rect_y = yOffset + ( y * ClientConnectionBean.tileHeight );
log.debug("rect_x,rect_y,tileWidth,tileHeight "+rect_x+","+rect_y+","+ClientConnectionBean.tileWidth+","+ClientConnectionBean.tileHeight);
int rectWidth = ClientConnectionBean.tileWidth;
int rectHeight = ClientConnectionBean.tileHeight;
//log.debug("-1- rectWidth,rectHeight"+rectWidth+","+rectHeight);
if (rect_x + rectWidth > screenSize.width) {
rectWidth = screenSize.width - rect_x;
}
if (rect_y + rectHeight > screenSize.height) {
rectHeight = screenSize.height - rect_y;
}
//log.debug("-2- rectWidth,rectHeight"+rectWidth+","+rectHeight);
if (rectWidth == 0 || rectHeight == 0) {
continue;
}
Rectangle screenRectangle = new Rectangle(rect_x,rect_y,rectWidth,rectHeight);
Rectangle shrinkedRectAngle = new Rectangle(Math.round(rect_x * ClientConnectionBean.imgQuality) , Math.round(rect_y * ClientConnectionBean.imgQuality),
Math.round(rectWidth * ClientConnectionBean.imgQuality), Math.round(rectHeight * ClientConnectionBean.imgQuality));
BufferedImage imageScreen = robot.createScreenCapture(screenRectangle);
int scaledWidth = Math.round(rectWidth * ClientConnectionBean.imgQuality);
int scaledHeight = Math.round(rectHeight * ClientConnectionBean.imgQuality);
Image img = imageScreen.getScaledInstance(scaledWidth, scaledHeight,Image.SCALE_SMOOTH);
//BufferedImage.TYPE_INT_RGB
//TYPE_3BYTE_BGR
BufferedImage image = new BufferedImage(scaledWidth, scaledHeight,BufferedImage.TYPE_3BYTE_BGR);
Graphics2D biContext = image.createGraphics();
biContext.drawImage(img, 0, 0, null);
// ByteArrayOutputStream out = new ByteArrayOutputStream();
//
// JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
// JPEGEncodeParam encpar = encoder.getDefaultJPEGEncodeParam(image);
//
// encpar.setQuality(ClientConnectionBean.imgQualityDefault, false);
// encoder.setJPEGEncodeParam(encpar);
// encoder.encode(image);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageWriter writer = ImageIO.getImageWritersByFormatName( "jpg" ).next();
ImageOutputStream ios = ImageIO.createImageOutputStream( out );
writer.setOutput( ios );
//ImageWriteParam param = writer.getDefaultWriteParam();
//log.debug("Logs "+param.getCompressionType());
//param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
//param.setCompressionQuality(ClientConnectionBean.imgQualityDefault);
ImageWriteParam iwparam = new JPEGImageWriteParam( Locale.getDefault() );
iwparam.setCompressionMode( ImageWriteParam.MODE_EXPLICIT ) ;
iwparam.setCompressionQuality( ClientConnectionBean.imgQualityDefault );
writer.write( null, new IIOImage(image, null, null), null );
ios.flush();
writer.dispose();
ios.close();
imageScreen.flush();
byte[] payload = out.toByteArray();
//GZip
ByteArrayOutputStream byteGzipOut = new ByteArrayOutputStream();
GZIPOutputStream gZipOut = new GZIPOutputStream(byteGzipOut);
gZipOut.write(payload);
gZipOut.close();
image.flush();
if (img!=null)img.flush();
log.debug("byteGzipOut LENGTH "+byteGzipOut.toByteArray().length);
log.debug("payload LENGTH "+payload.length);
clientImageFrames.add(new ClientImageFrame(shrinkedRectAngle,byteGzipOut.toByteArray()));
}
}
return clientImageFrames;
} catch (Exception err) {
log.error("[checkFrame]",err);
}
return null;
}
}