Solution: First using reduce image quality, I defined
- maximum image size is: ex: 1048576
Take a screenshot to a file (you choose is a base64 is up to you)
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ImageObserver;
import java.awt.image.RenderedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.Iterator;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;
/**
@author daviddoan
*
*/
public class ScreenShotUtils implements ImageObserver {
private static final Color BKGROUND_COLOR = Color.WHITE;
private boolean imageLoaded = false;
private static BufferedImage matrixTransparentPixels(BufferedImage originalBufferedImage, Color fillColor) {
int w = originalBufferedImage.getWidth();
int h = originalBufferedImage.getHeight();
BufferedImage newGeneratedBufferedImage;
if (originalBufferedImage.getType() == BufferedImage.TYPE_4BYTE_ABGR) {
newGeneratedBufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
} else {
newGeneratedBufferedImage = new BufferedImage(w, h, originalBufferedImage.getType());
}
// clone the original image
Graphics2D graphics2D = null;
try {
graphics2D = newGeneratedBufferedImage.createGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
final boolean isDrawingSuccess = graphics2D.drawImage(originalBufferedImage, 0, 0, w, h, fillColor, null);
if (!isDrawingSuccess) {
while (!imageLoaded) {
System.err.println("DRAWING IMAGE, PLEASE WAITING...");
Thread.sleep(10000);
}
}
} finally {
if (graphics2D != null) {
graphics2D.dispose();
}
}
return newGeneratedBufferedImage;
}
public static void reduceScreenShotQuality(File screenshotSource, String location, String fileName, String fileExtension) throws Exception {
int sizeThreshold = 1048576;
float quality = 1.0f;
long fileSize = screenshotSource.length();
if (fileSize <= sizeThreshold) {
// Image file size is small, no need reduced any more.;
writeImageToLocation(screenshotSource, location, fileName, "jpeg");
return;
}
// Need to reduce 'cos over sizeThreshold
ImageWriter writer = createImageWriter();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
InputStream inputStream = new FileInputStream(screenshotSource);
FileImageOutputStream output = getOutputStream(location, fileName, fileExtension);
BufferedImage originalImage = ImageIO.read(inputStream);
BufferedImage newBufferedImage;
newBufferedImage = matrixTransparentPixels(originalImage, BKGROUND_COLOR);
float percent = 0.1f; // 10% of 1
while (fileSize > sizeThreshold) {
if (percent >= quality) {
percent = percent * 0.1f;
}
quality -= percent;
iwp.setCompressionQuality(quality);
writeImage(writer, newBufferedImage, output, iwp);
File fileOut2 = new File(location + fileName + "." + fileExtension);
long newFileSize = fileOut2.length();
if (newFileSize == fileSize) {
// cannot reduce more
break;
} else {
fileSize = newFileSize;
}
}
// Flush all stream
inputStream.close();
originalImage.flush();
newBufferedImage.flush();
writer.dispose();
}
private static void writeImage(ImageWriter writer, BufferedImage bufferedImage, FileImageOutputStream output, ImageWriteParam iwp) {
try {
IIOImage image = new IIOImage(bufferedImage, null, null);
writer.setOutput(output);
if (iwp != null) {
writer.write(null, image, iwp);
} else {
writer.write(image);
}
output.close();
} catch (IOException e) {
System.err.println("writeImage: IOException- " + e.getMessage());
} finally {
System.err.println("End writeImage");
}
}
private static FileImageOutputStream getOutputStream(String location, String fileName, String fileExtension) throws FileNotFoundException, IOException {
File fileOut = new File(location + fileName + "." + fileExtension);
if (fileOut.exists()) {
fileOut.delete();
}
FileImageOutputStream output = new FileImageOutputStream(fileOut);
return output;
}
private static ImageWriter createImageWriter() {
Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter writer = (ImageWriter) iter.next();
return writer;
}
private static void writeImageToLocation(File filePng, String location, String fileName, String extension) throws IOException {
ImageWriter writer = createImageWriter();
ImageWriteParam iwp = writer.getDefaultWriteParam();
SeekableStream seekableStream = new FileSeekableStream(filePng);
PNGDecodeParam pngParams = new PNGDecodeParam();
ImageDecoder dec = ImageCodec.createImageDecoder("png", seekableStream, pngParams);
RenderedImage pngImage = dec.decodeAsRenderedImage();
BufferedImage newImage = new BufferedImage(pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_INT_RGB);
newImage.createGraphics().drawImage(renderedImageToBufferedImage(pngImage), 0, 0, Color.BLACK, null);
FileImageOutputStream output = getOutputStream(location, fileName, extension);
writeImage(writer, newImage, output, iwp);
newImage.flush();
seekableStream.close();
writer.dispose();
}
private static BufferedImage renderedImageToBufferedImage(RenderedImage img) {
if (img instanceof BufferedImage) {
return (BufferedImage) img;
}
ColorModel cm = img.getColorModel();
int width = img.getWidth();
int height = img.getHeight();
WritableRaster raster = cm.createCompatibleWritableRaster(width, height);
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
Hashtable properties = new Hashtable();
String[] keys = img.getPropertyNames();
if (keys != null) {
for (String key : keys) {
properties.put(key, img.getProperty(key));
}
}
BufferedImage result = new BufferedImage(cm, raster, isAlphaPremultiplied, properties);
img.copyData(raster);
return result;
}
}
@Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
if (infoflags != ALLBITS) {
// Image has not finished loading!
// Return true to tell the image loading thread to keep drawing until image fully loads.
return true;
} else {
imageLoaded = true;
return false;
}
}
- Solution: Write as a thumbnail image (heigh x width)
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import org.apache.log4j.Logger;
import com.sun.media.jai.codec.SeekableStream;
/**