package screensaver; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import java.util.*; import com.sun.image.codec.jpeg.*; import java.awt.Image; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.awt.image.MemoryImageSource; import java.io.FileInputStream; import java.io.FileOutputStream; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; public class ScreenPicSaver { MediaTracker tracker = new MediaTracker(new Component() {}); public ScreenPicSaver() {} public Image loadbitmap(String sdir, String sfile) //读取8位或24位的位图文件 { Image image; System.out.println("loading:" + sdir + sfile); try { FileInputStream fs = new FileInputStream(sdir + sfile); int bflen = 14; // 14 字节 BITMAPFILEHEADER byte bf[] = new byte[bflen]; fs.read(bf, 0, bflen); int bilen = 40; // 40 字节 BITMAPINFOHEADER byte bi[] = new byte[bilen]; fs.read(bi, 0, bilen); // 解释数据。 int nsize = ( ( (int) bf[5] & 0xff) << 24) | ( ( (int) bf[4] & 0xff) << 16) | ( ( (int) bf[3] & 0xff) << 8) | (int) bf[2] & 0xff; System.out.println("File type is :" + (char) bf[0] + (char) bf[1]); System.out.println("Size of file is :" + nsize); int nbisize = ( ( (int) bi[3] & 0xff) << 24) | ( ( (int) bi[2] & 0xff) << 16) | ( ( (int) bi[1] & 0xff) << 8) | (int) bi[0] & 0xff; System.out.println("Size of bitmapinfoheader is :" + nbisize); int nwidth = ( ( (int) bi[7] & 0xff) << 24) | ( ( (int) bi[6] & 0xff) << 16) | ( ( (int) bi[5] & 0xff) << 8) | (int) bi[4] & 0xff; System.out.println("Width is :" + nwidth); int nheight = ( ( (int) bi[11] & 0xff) << 24) | ( ( (int) bi[10] & 0xff) << 16) | ( ( (int) bi[9] & 0xff) << 8) | (int) bi[8] & 0xff; System.out.println("Height is :" + nheight); int nplanes = ( ( (int) bi[13] & 0xff) << 8) | (int) bi[12] & 0xff; System.out.println("Planes is :" + nplanes); int nbitcount = ( ( (int) bi[15] & 0xff) << 8) | (int) bi[14] & 0xff; System.out.println("BitCount is :" + nbitcount); // 查找表明压缩的非零值 int ncompression = ( ( (int) bi[19]) << 24) | ( ( (int) bi[18]) << 16) | ( ( (int) bi[17]) << 8) | (int) bi[16]; System.out.println("Compression is :" + ncompression); int nsizeimage = ( ( (int) bi[23] & 0xff) << 24) | ( ( (int) bi[22] & 0xff) << 16) | ( ( (int) bi[21] & 0xff) << 8) | (int) bi[20] & 0xff; System.out.println("SizeImage is :" + nsizeimage); int nxpm = ( ( (int) bi[27] & 0xff) << 24) | ( ( (int) bi[26] & 0xff) << 16) | ( ( (int) bi[25] & 0xff) << 8) | (int) bi[24] & 0xff; System.out.println("X-Pixels per meter is :" + nxpm); int nypm = ( ( (int) bi[31] & 0xff) << 24) | ( ( (int) bi[30] & 0xff) << 16) | ( ( (int) bi[29] & 0xff) << 8) | (int) bi[28] & 0xff; System.out.println("Y-Pixels per meter is :" + nypm); int nclrused = ( ( (int) bi[35] & 0xff) << 24) | ( ( (int) bi[34] & 0xff) << 16) | ( ( (int) bi[33] & 0xff) << 8) | (int) bi[32] & 0xff; System.out.println("Colors used are :" + nclrused); int nclrimp = ( ( (int) bi[39] & 0xff) << 24) | ( ( (int) bi[38] & 0xff) << 16) | ( ( (int) bi[37] & 0xff) << 8) | (int) bi[36] & 0xff; System.out.println("Colors important are :" + nclrimp); if (nbitcount == 24) { // 24 位格式不包含调色板数据,但扫描行被补足到 // 4 个字节。 int npad = (nsizeimage / nheight) - nwidth * 3; int ndata[] = new int[nheight * nwidth]; byte brgb[] = new byte[ (nwidth + npad) * 3 * nheight]; fs.read(brgb, 0, (nwidth + npad) * 3 * nheight); int nindex = 0; for (int j = 0; j < nheight; j++) { for (int i = 0; i < nwidth; i++) { ndata[nwidth * (nheight - j - 1) + i] = (255 & 0xff) << 24 | ( ( (int) brgb[nindex + 2] & 0xff) << 16) | ( ( (int) brgb[nindex + 1] & 0xff) << 8) | (int) brgb[nindex] & 0xff; /** System.out.println("Encoded Color at (" +i + "," + j + ")is:" + nrgb + " (R,G,B)= (" + ( (int) (brgb[2]) & 0xff) + "," + ( (int) brgb[1] & 0xff) + "," + ( (int) brgb[0] & 0xff) + ")"); }*/ nindex += 3; } nindex += npad; } image = Toolkit.getDefaultToolkit().createImage (new MemoryImageSource(nwidth, nheight, ndata, 0, nwidth)); } else if (nbitcount == 8) { // 必须确定颜色数。如果 clrsused 参数大于 0, // 则颜色数由它决定。如果它等于 0,则根据 // bitsperpixel 计算颜色数。 int nNumColors = 0; if (nclrused > 0) { nNumColors = nclrused; } else { nNumColors = (1 & 0xff) << nbitcount; } System.out.println("The number of Colors is" + nNumColors); // 某些位图不计算 sizeimage 域,请找出 // 这些情况并对它们进行修正。 if (nsizeimage == 0) { nsizeimage = ( ( ( (nwidth * nbitcount) + 31) & ~31) >> 3); nsizeimage *= nheight; System.out.println("nsizeimage (backup) is" + nsizeimage); } // 读取调色板颜色。 int npalette[] = new int[nNumColors]; byte bpalette[] = new byte[nNumColors * 4]; fs.read(bpalette, 0, nNumColors * 4); int nindex8 = 0; for (int n = 0; n < nNumColors; n++) { npalette[n] = (255 & 0xff) << 24 | ( ( (int) bpalette[nindex8 + 2] & 0xff) << 16) | ( ( (int) bpalette[nindex8 + 1] & 0xff) << 8) | (int) bpalette[nindex8] & 0xff; /**System.out.println ("Palette Color "+n +" is:" + npalette[n] + " (res,R,G,B)= (" + ( (int) (bpalette[nindex8 + 3]) & 0xff) + "," + ( (int) (bpalette[nindex8 + 2]) & 0xff) + "," + ( (int) bpalette[nindex8 + 1] & 0xff) + "," + ( (int) bpalette[nindex8] & 0xff) + ")"); */ nindex8 += 4; } // 读取图像数据(实际上是调色板的索引) // 扫描行仍被补足到 4 个字节。 int npad8 = (nsizeimage / nheight) - nwidth; System.out.println("nPad is:" + npad8); int ndata8[] = new int[nwidth * nheight]; byte bdata[] = new byte[ (nwidth + npad8) * nheight]; fs.read(bdata, 0, (nwidth + npad8) * nheight); nindex8 = 0; for (int j8 = 0; j8 < nheight; j8++) { for (int i8 = 0; i8 < nwidth; i8++) { ndata8[nwidth * (nheight - j8 - 1) + i8] = npalette[ ( (int) bdata[nindex8] & 0xff)]; nindex8++; } nindex8 += npad8; } image = Toolkit.getDefaultToolkit().createImage (new MemoryImageSource(nwidth, nheight, ndata8, 0, nwidth)); } else { System.out.println("Not a 24-bit or 8-bit Windows Bitmap, aborting..."); image = (Image)null; } fs.close(); return image; } catch (Exception e) { System.out.println("Caught exception in loadbitmap!"); } return (Image)null; } public void waitForImage(Image image) { //tracker = new MediaTracker(this); try { tracker.addImage(image, 0); //public void addImage(Image image,int id) //tracker.waitForAll(); tracker.waitForID(0); tracker.checkAll(true); /** while(!tracker.checkID(0)) { tracker.waitForID(0); }*/ if (tracker.isErrorAny()) { // System.out.println(tracker.getErrorsAny().toString()); System.out.println("加载图像出现错误!"); System.exit(0); } // loadStatus = tracker.statusID( 0, false ); // tracker.removeImage(image, 0); } catch (InterruptedException e) { e.printStackTrace(); } } // waitForImage public void checkImage(Image image) { waitForImage(image); int imageWidth = image.getWidth(null); if (imageWidth < 1) { throw new IllegalArgumentException("image width " + imageWidth + " is out of range"); } int imageHeight = image.getHeight(null); if (imageHeight < 1) { throw new IllegalArgumentException("image height " + imageHeight + " is out of range"); } // System.out.println( "Image size=" + imageWidth + "x" + imageHeight ); } // checkImage public void encodeJPEG(OutputStream outputStream, Image outputImage, float outputQuality) throws java.io.IOException { int outputWidth = outputImage.getWidth(null); if (outputWidth < 1) { throw new IllegalArgumentException("output image width " + outputWidth + " is out of range"); } int outputHeight = outputImage.getHeight(null); if (outputHeight < 1) { throw new IllegalArgumentException("output image height " + outputHeight + " is out of range"); } // Get a buffered image from the image. BufferedImage bi = new BufferedImage(outputWidth, outputHeight, BufferedImage.TYPE_INT_RGB); Graphics2D biContext = bi.createGraphics(); biContext.drawImage(outputImage, 0, 0, null); // Note that additional drawing such as watermarks or logos can be placed here. // com.sun.image.codec.jpeg package is included in sun and ibm sdk 1.3 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outputStream); // The default quality is 0.75. JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(bi); jep.setQuality(outputQuality, true); encoder.encode(bi, jep); // encoder.encode( bi ); outputStream.flush(); } // encodeImage /** Adjusts the size of the image to the given coordinates. * If width or height is -1, the image aspect ration is maintained. * <p> * Hints are one of SCALE_DEFAULT, SCALE_FAST, SCALE_SMOOTH, * SCALE_REPLICATE, SCALE_AREA_AVERAGING as defined in java.awt.Image. */ public Image setSize(Image image, int width, int height, int hints) { return image.getScaledInstance(width, height, hints); } // setSize public Image setSize(Image image, int width, int height) { return setSize(image, width, height, java.awt.Image.SCALE_DEFAULT); //setSize调用的是上一个方法. } // setSize //Component initialization public static void main(String[] args) { ScreenPicSaver sps = new ScreenPicSaver(); // String sdir = new String("d:\\"); // String sfile = new String("desktop.bmp"); String outputFileName = new String("d:\\desktop.jpg"); //Image inputImage = Toolkit.getDefaultToolkit().getImage(inputFileName); //Image inputImage = sps.loadbitmap(sdir, sfile); //=============================================================== BufferedImage bufferedImage = null; Robot robot; Image inputImage = null; try { robot = new Robot(); bufferedImage = robot.createScreenCapture(new Rectangle(Toolkit. getDefaultToolkit().getScreenSize())); //得到桌面图像的bufferedImage对象 } catch (Exception ex) { ex.printStackTrace(); } int width = bufferedImage.getWidth(); int height = bufferedImage.getHeight(); inputImage = bufferedImage.getScaledInstance(width, height, BufferedImage.TYPE_INT_RGB); //将bufferedImage对象转化位Image对象 MediaTracker tracker = new MediaTracker(new Component() {}); int outputWidth = inputImage.getWidth(null); //使得新图像和原图像的宽度一样 float outputQuality = 0.80f; Image outputImage = sps.setSize(inputImage, outputWidth, -1); //-1表示在宽度确定的情况下,高度在原图像的基础上成比例缩放 try { tracker.addImage(inputImage, 0); //sps.tracker.waitForAll(); tracker.waitForID(0); tracker.checkAll(true); } catch (InterruptedException e) { e.printStackTrace(); } int imageWidth = inputImage.getWidth(null); if (imageWidth < 1) { throw new IllegalArgumentException("image width " + imageWidth + " is out of range"); } int imageHeight = inputImage.getHeight(null); if (imageHeight < 1) { throw new IllegalArgumentException("image height " + imageHeight + " is out of range"); } try { FileOutputStream fos = new FileOutputStream(outputFileName); sps.encodeJPEG(fos, outputImage, outputQuality); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); } System.exit(0); } } 
|