使用 Selenium Webdriver TakesScreenshot 方法捕获 base64 图像。我可以减小图像尺寸吗?
Using Selenium Webdriver TakesScreenshot method to capture a base64 image. Can I reduce the image size?
我正在使用 Selenium 的 TakesScreenshot 方法将 base64 字符串添加到我的 HTML 报告中。报告 (extentreports) 中生成的屏幕截图有点太大,部分被推到屏幕外。缩小它也会减小报告的文件大小。
我可以截取更小的 base64 屏幕截图吗?将其缩小约 20% 将是完美的……或者我是否必须先将图像创建为 File
,然后将其缩小,然后转换为 base64。
public static String CaptureScreen(WebDriver driver) {
TakesScreenshot newScreen = (TakesScreenshot) driver;
String scnShot = newScreen.getScreenshotAs(OutputType.BASE64);
return "data:image/jpg;base64, " + scnShot ;
}
如果您想截取较小的屏幕截图文件。您应该降低图像质量或写入具有固定尺寸(高度 x 宽度)的文件。让我们检查一下我的解决方案,希望对您有所帮助:
图书馆:
<!-- SELENIUM LIBs and Image Process LIBs -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>2.41.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.41.0</version>
</dependency>
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
<dependency>
<groupId>com.sun.media</groupId>
<artifactId>jai_codec</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>javax.media</groupId>
<artifactId>jai_core</artifactId>
<version>1.1.3</version>
</dependency>
解决方法:首先使用reduce image quality,我定义
- 最大图像大小为:例如:1048576
截屏到文件(你选择是不是base64由你决定)
</p>
<p>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;</p>
<p>/**</p>
<ul>
<li><p>@author daviddoan
*
*/
public class ScreenShotUtils implements ImageObserver {</p>
<p>private static final Color BKGROUND_COLOR = Color.WHITE;
private boolean imageLoaded = false;</p>
<p>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();
}
}</p>
<p>return newGeneratedBufferedImage;
}</p>
<p>public static void reduceScreenShotQuality(File screenshotSource, String location, String fileName, String fileExtension) throws Exception {</p>
<p>int sizeThreshold = 1048576;
float quality = 1.0f;
long fileSize = screenshotSource.length();</p>
<p>if (fileSize <= sizeThreshold) {
// Image file size is small, no need reduced any more.;
writeImageToLocation(screenshotSource, location, fileName, "jpeg");
return;
}</p>
<p>// Need to reduce 'cos over sizeThreshold</p>
<p>ImageWriter writer = createImageWriter();</p>
<p>ImageWriteParam iwp = writer.getDefaultWriteParam();</p>
<p>iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);</p>
<p>InputStream inputStream = new FileInputStream(screenshotSource);</p>
<p>FileImageOutputStream output = getOutputStream(location, fileName, fileExtension);</p>
<p>BufferedImage originalImage = ImageIO.read(inputStream);
BufferedImage newBufferedImage;</p>
<p>newBufferedImage = matrixTransparentPixels(originalImage, BKGROUND_COLOR);</p>
<p>float percent = 0.1f; // 10% of 1</p>
<p>while (fileSize > sizeThreshold) {
if (percent >= quality) {
percent = percent * 0.1f;
}</p>
<p>quality -= percent;</p>
<p>iwp.setCompressionQuality(quality);</p>
<p>writeImage(writer, newBufferedImage, output, iwp);</p>
<p>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();
}</p>
<p>private static void writeImage(ImageWriter writer, BufferedImage bufferedImage, FileImageOutputStream output, ImageWriteParam iwp) {
try {
IIOImage image = new IIOImage(bufferedImage, null, null);
writer.setOutput(output);</p>
<p>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");
}</p>
<p>}</p>
<p>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);</p>
<p>return output;
}</p>
<p>private static ImageWriter createImageWriter() {
Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter writer = (ImageWriter) iter.next();
return writer;
}</p>
<p>private static void writeImageToLocation(File filePng, String location, String fileName, String extension) throws IOException {
ImageWriter writer = createImageWriter();</p>
<p>ImageWriteParam iwp = writer.getDefaultWriteParam();</p>
<p>SeekableStream seekableStream = new FileSeekableStream(filePng);
PNGDecodeParam pngParams = new PNGDecodeParam();
ImageDecoder dec = ImageCodec.createImageDecoder("png", seekableStream, pngParams);
RenderedImage pngImage = dec.decodeAsRenderedImage();</p>
<p>BufferedImage newImage = new BufferedImage(pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_INT_RGB);</p>
<p>newImage.createGraphics().drawImage(renderedImageToBufferedImage(pngImage), 0, 0, Color.BLACK, null);</p>
<p>FileImageOutputStream output = getOutputStream(location, fileName, extension);
writeImage(writer, newImage, output, iwp);</p>
<p>newImage.flush();
seekableStream.close();
writer.dispose();
}</p>
<p>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;
}
}
</pre>
- 解决方案:写成缩略图(高 x 宽)
</p>
<p>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;</p>
<p>import javax.imageio.ImageIO;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;</p>
<p>import org.apache.log4j.Logger;</p>
<p>import com.sun.media.jai.codec.SeekableStream;</p>
<p>/**</p>
<ul>
<li><ul>
<li>@author daviddoan
*
*/</li>
</ul></li>
</ul>
<p>public class ThumbnailUtils implements ImageObserver {</p>
<pre><code>private static final String CLASS_NAME = ThumbnailUtils.class.getSimpleName();
private final Color BKGROUND_COLOR = Color.WHITE;
private boolean imageLoaded = false;
public void writeThumbnail(String originalImagePath, int thumbWidth, int thumbHeight, String thumbImagePath)
throws Exception {
InputStream originalImageStream = new FileInputStream(originalImagePath);
File fileOut = new File(thumbImagePath);
if (fileOut.exists()) {
fileOut.delete();
}
OutputStream thumbImageOutStream = new FileOutputStream(fileOut);
writeThumbnail(originalImageStream, thumbWidth, thumbHeight, thumbImageOutStream);
thumbImageOutStream.close();
originalImageStream.close();
}
public void writeThumbnail(File file, int thumbWidth, int thumbHeight, String thumbImagePath) throws Exception {
InputStream originalImageStream = new FileInputStream(file);
File fileOut = new File(thumbImagePath);
if (fileOut.exists()) {
fileOut.delete();
}
OutputStream thumbImageOutStream = new FileOutputStream(fileOut);
writeThumbnail(originalImageStream, thumbWidth, thumbHeight, thumbImageOutStream);
thumbImageOutStream.close();
originalImageStream.close();
}
private void writeThumbnail(InputStream originalImageStream, int thumbWidth, int thumbHeight,
OutputStream thumbImageOutStream) throws Exception {
ByteArrayOutputStream byteArrOutputStream = null;
try {
byteArrOutputStream = makeThumbnail(originalImageStream, thumbWidth, thumbHeight);
byteArrOutputStream.writeTo(thumbImageOutStream);
byteArrOutputStream.flush();
} finally {
if (byteArrOutputStream != null) {
byteArrOutputStream.close();
}
}
}
private Image makeThumbnail(final Image originalImage, final int maxWidth, final int maxHeight) throws Exception {
// ImageOveserve is ingnored for BufferedImages
final int photoWidth = originalImage.getWidth(null);
final int photoHeight = originalImage.getHeight(null);
int thumbWidth = maxWidth;
int thumbHeight = maxHeight;
final double thumbRatio = (double) thumbWidth / (double) thumbHeight;
final double photoRatio = (double) photoWidth / (double) photoHeight;
if (thumbRatio < photoRatio)
thumbHeight = (int) (thumbWidth / photoRatio);
else
thumbWidth = (int) (thumbHeight * photoRatio);
// Checking if the photo's size is smaller than thumbnail's size: getting the original size
if (photoWidth < thumbWidth) {
thumbWidth = photoWidth;
}
if (photoHeight < thumbHeight) {
thumbHeight = photoHeight;
}
final BufferedImage thumbnailBufferedImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB);
final Graphics2D graphics2D = thumbnailBufferedImage.createGraphics();
// Best Quality Render Hints!
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
graphics2D.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
graphics2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
final AffineTransform t = new AffineTransform();
t.scale((double) thumbWidth / photoWidth, (double) thumbHeight / photoHeight);
graphics2D.setBackground(BKGROUND_COLOR);
final boolean complete = graphics2D.drawImage(originalImage, t, this);
if (!complete) {
while (!imageLoaded) {
try {
wait(100);
} catch (InterruptedException ie) {
}
}
}
graphics2D.dispose();
return thumbnailBufferedImage;
}
private synchronized ByteArrayOutputStream makeThumbnail(final InputStream originalImageStream, final int maxWidth,
final int maxHeight) throws Exception {
SeekableStream seekableStream = SeekableStream.wrapInputStream(originalImageStream, true);
RenderedOp reop = JAI.create("stream", seekableStream);
Image photo = reop.getAsBufferedImage();
final BufferedImage thumbnail = (BufferedImage) makeThumbnail(photo, maxWidth, maxHeight);
final ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
ImageIO.write(thumbnail, GlobalResourceUtils.getFileExtension(), byteArrayStream);
return byteArrayStream;
}
@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;
}
}
}
希望对您有所帮助:)
我正在使用 Selenium 的 TakesScreenshot 方法将 base64 字符串添加到我的 HTML 报告中。报告 (extentreports) 中生成的屏幕截图有点太大,部分被推到屏幕外。缩小它也会减小报告的文件大小。
我可以截取更小的 base64 屏幕截图吗?将其缩小约 20% 将是完美的……或者我是否必须先将图像创建为 File
,然后将其缩小,然后转换为 base64。
public static String CaptureScreen(WebDriver driver) {
TakesScreenshot newScreen = (TakesScreenshot) driver;
String scnShot = newScreen.getScreenshotAs(OutputType.BASE64);
return "data:image/jpg;base64, " + scnShot ;
}
如果您想截取较小的屏幕截图文件。您应该降低图像质量或写入具有固定尺寸(高度 x 宽度)的文件。让我们检查一下我的解决方案,希望对您有所帮助:
图书馆:
<!-- SELENIUM LIBs and Image Process LIBs -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>2.41.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.41.0</version>
</dependency>
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
<dependency>
<groupId>com.sun.media</groupId>
<artifactId>jai_codec</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>javax.media</groupId>
<artifactId>jai_core</artifactId>
<version>1.1.3</version>
</dependency>
解决方法:首先使用reduce image quality,我定义
- 最大图像大小为:例如:1048576
截屏到文件(你选择是不是base64由你决定)
</p> <p>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;</p> <p>/**</p> <ul> <li><p>@author daviddoan * */ public class ScreenShotUtils implements ImageObserver {</p> <p>private static final Color BKGROUND_COLOR = Color.WHITE; private boolean imageLoaded = false;</p> <p>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(); } }</p> <p>return newGeneratedBufferedImage; }</p> <p>public static void reduceScreenShotQuality(File screenshotSource, String location, String fileName, String fileExtension) throws Exception {</p> <p>int sizeThreshold = 1048576; float quality = 1.0f; long fileSize = screenshotSource.length();</p> <p>if (fileSize <= sizeThreshold) { // Image file size is small, no need reduced any more.; writeImageToLocation(screenshotSource, location, fileName, "jpeg"); return; }</p> <p>// Need to reduce 'cos over sizeThreshold</p> <p>ImageWriter writer = createImageWriter();</p> <p>ImageWriteParam iwp = writer.getDefaultWriteParam();</p> <p>iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);</p> <p>InputStream inputStream = new FileInputStream(screenshotSource);</p> <p>FileImageOutputStream output = getOutputStream(location, fileName, fileExtension);</p> <p>BufferedImage originalImage = ImageIO.read(inputStream); BufferedImage newBufferedImage;</p> <p>newBufferedImage = matrixTransparentPixels(originalImage, BKGROUND_COLOR);</p> <p>float percent = 0.1f; // 10% of 1</p> <p>while (fileSize > sizeThreshold) { if (percent >= quality) { percent = percent * 0.1f; }</p> <p>quality -= percent;</p> <p>iwp.setCompressionQuality(quality);</p> <p>writeImage(writer, newBufferedImage, output, iwp);</p> <p>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(); }</p> <p>private static void writeImage(ImageWriter writer, BufferedImage bufferedImage, FileImageOutputStream output, ImageWriteParam iwp) { try { IIOImage image = new IIOImage(bufferedImage, null, null); writer.setOutput(output);</p> <p>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"); }</p> <p>}</p> <p>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);</p> <p>return output; }</p> <p>private static ImageWriter createImageWriter() { Iterator iter = ImageIO.getImageWritersByFormatName("jpeg"); ImageWriter writer = (ImageWriter) iter.next(); return writer; }</p> <p>private static void writeImageToLocation(File filePng, String location, String fileName, String extension) throws IOException { ImageWriter writer = createImageWriter();</p> <p>ImageWriteParam iwp = writer.getDefaultWriteParam();</p> <p>SeekableStream seekableStream = new FileSeekableStream(filePng); PNGDecodeParam pngParams = new PNGDecodeParam(); ImageDecoder dec = ImageCodec.createImageDecoder("png", seekableStream, pngParams); RenderedImage pngImage = dec.decodeAsRenderedImage();</p> <p>BufferedImage newImage = new BufferedImage(pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_INT_RGB);</p> <p>newImage.createGraphics().drawImage(renderedImageToBufferedImage(pngImage), 0, 0, Color.BLACK, null);</p> <p>FileImageOutputStream output = getOutputStream(location, fileName, extension); writeImage(writer, newImage, output, iwp);</p> <p>newImage.flush(); seekableStream.close(); writer.dispose(); }</p> <p>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; } } </pre>
- 解决方案:写成缩略图(高 x 宽)
</p>
<p>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;</p>
<p>import javax.imageio.ImageIO;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;</p>
<p>import org.apache.log4j.Logger;</p>
<p>import com.sun.media.jai.codec.SeekableStream;</p>
<p>/**</p>
<ul>
<li><ul>
<li>@author daviddoan
*
*/</li>
</ul></li>
</ul>
<p>public class ThumbnailUtils implements ImageObserver {</p>
<pre><code>private static final String CLASS_NAME = ThumbnailUtils.class.getSimpleName();
private final Color BKGROUND_COLOR = Color.WHITE;
private boolean imageLoaded = false;
public void writeThumbnail(String originalImagePath, int thumbWidth, int thumbHeight, String thumbImagePath)
throws Exception {
InputStream originalImageStream = new FileInputStream(originalImagePath);
File fileOut = new File(thumbImagePath);
if (fileOut.exists()) {
fileOut.delete();
}
OutputStream thumbImageOutStream = new FileOutputStream(fileOut);
writeThumbnail(originalImageStream, thumbWidth, thumbHeight, thumbImageOutStream);
thumbImageOutStream.close();
originalImageStream.close();
}
public void writeThumbnail(File file, int thumbWidth, int thumbHeight, String thumbImagePath) throws Exception {
InputStream originalImageStream = new FileInputStream(file);
File fileOut = new File(thumbImagePath);
if (fileOut.exists()) {
fileOut.delete();
}
OutputStream thumbImageOutStream = new FileOutputStream(fileOut);
writeThumbnail(originalImageStream, thumbWidth, thumbHeight, thumbImageOutStream);
thumbImageOutStream.close();
originalImageStream.close();
}
private void writeThumbnail(InputStream originalImageStream, int thumbWidth, int thumbHeight,
OutputStream thumbImageOutStream) throws Exception {
ByteArrayOutputStream byteArrOutputStream = null;
try {
byteArrOutputStream = makeThumbnail(originalImageStream, thumbWidth, thumbHeight);
byteArrOutputStream.writeTo(thumbImageOutStream);
byteArrOutputStream.flush();
} finally {
if (byteArrOutputStream != null) {
byteArrOutputStream.close();
}
}
}
private Image makeThumbnail(final Image originalImage, final int maxWidth, final int maxHeight) throws Exception {
// ImageOveserve is ingnored for BufferedImages
final int photoWidth = originalImage.getWidth(null);
final int photoHeight = originalImage.getHeight(null);
int thumbWidth = maxWidth;
int thumbHeight = maxHeight;
final double thumbRatio = (double) thumbWidth / (double) thumbHeight;
final double photoRatio = (double) photoWidth / (double) photoHeight;
if (thumbRatio < photoRatio)
thumbHeight = (int) (thumbWidth / photoRatio);
else
thumbWidth = (int) (thumbHeight * photoRatio);
// Checking if the photo's size is smaller than thumbnail's size: getting the original size
if (photoWidth < thumbWidth) {
thumbWidth = photoWidth;
}
if (photoHeight < thumbHeight) {
thumbHeight = photoHeight;
}
final BufferedImage thumbnailBufferedImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB);
final Graphics2D graphics2D = thumbnailBufferedImage.createGraphics();
// Best Quality Render Hints!
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
graphics2D.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
graphics2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
final AffineTransform t = new AffineTransform();
t.scale((double) thumbWidth / photoWidth, (double) thumbHeight / photoHeight);
graphics2D.setBackground(BKGROUND_COLOR);
final boolean complete = graphics2D.drawImage(originalImage, t, this);
if (!complete) {
while (!imageLoaded) {
try {
wait(100);
} catch (InterruptedException ie) {
}
}
}
graphics2D.dispose();
return thumbnailBufferedImage;
}
private synchronized ByteArrayOutputStream makeThumbnail(final InputStream originalImageStream, final int maxWidth,
final int maxHeight) throws Exception {
SeekableStream seekableStream = SeekableStream.wrapInputStream(originalImageStream, true);
RenderedOp reop = JAI.create("stream", seekableStream);
Image photo = reop.getAsBufferedImage();
final BufferedImage thumbnail = (BufferedImage) makeThumbnail(photo, maxWidth, maxHeight);
final ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
ImageIO.write(thumbnail, GlobalResourceUtils.getFileExtension(), byteArrayStream);
return byteArrayStream;
}
@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;
}
}
}
希望对您有所帮助:)