/** * * Copyright 2008 - 2009 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loon * @author cping * @email:javachenpeng@yahoo.com * @version 0.1 */ package loon; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.MediaTracker; import java.awt.Panel; import java.awt.Point; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.DataBufferInt; import java.awt.image.DirectColorModel; import java.awt.image.PixelGrabber; import java.awt.image.Raster; import java.awt.image.SampleModel; import java.awt.image.SinglePixelPackedSampleModel; import java.awt.image.WritableRaster; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; import java.util.Map.Entry; import loon.core.graphics.device.LColor; import loon.core.resource.Resources; import loon.jni.NativeSupport; import loon.utils.StringUtils; @SuppressWarnings({ "unchecked", "rawtypes" }) final public class JavaSEGraphicsUtils { // 自定义的RGB配色器 final static private DirectColorModel COLOR_MODEL_RGB = new DirectColorModel( 24, 0xFF0000, 0x00FF00, 0x0000FF); // 自定义的ARGB配色器 final static private DirectColorModel COLOR_MODEL_ARGB = new DirectColorModel( 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); final static public Toolkit toolKit = Toolkit.getDefaultToolkit(); final static private Map cacheImages = Collections .synchronizedMap(new HashMap(LSystem.DEFAULT_MAX_CACHE_SIZE)); // 此部分不要求缓存必然有效,故采用WeakHashMap final static private Map cacheByteImages = new WeakHashMap( LSystem.DEFAULT_MAX_CACHE_SIZE); // 优秀但缓慢的图像加载方式 final static RenderingHints hints_excellent; // 一般的图像加载 final static RenderingHints hints_general; // 低劣但高效的图像加载方式 final static RenderingHints hints_poor; static { // 设定图像显示状态为一般 hints_general = new RenderingHints(null); // 设定图像显示状态为优秀 hints_excellent = new RenderingHints( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); hints_excellent.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); hints_excellent.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); hints_excellent.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); hints_excellent.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); hints_excellent.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); hints_excellent.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); hints_excellent.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); hints_excellent.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); // 设定图像显示状态为低劣 hints_poor = new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); hints_poor.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP); hints_poor.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); hints_poor.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED); hints_poor.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED); hints_poor.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE); hints_poor.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED); hints_poor.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); hints_poor.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF); hints_poor.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED); hints_poor.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); hints_poor.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); hints_poor.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED); } private JavaSEGraphicsUtils() { } public static Image newRGBImage(int[] rgb, int width, int height, boolean processAlpha) { if (rgb == null) { throw new NullPointerException(); } if (width <= 0 || height <= 0) { throw new IllegalArgumentException(); } BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); if (!processAlpha) { int l = rgb.length; int[] rgbAux = new int[l]; for (int i = 0; i < l; i++) { rgbAux[i] = rgb[i] | 0xff000000; } rgb = rgbAux; } img.setRGB(0, 0, width, height, rgb, 0, width); return img; } /** * 生成对应指定像素的RGB模式BufferedImage * * @param pixels * @param w * @param h * @param pixelsSize * @return */ public static BufferedImage newAwtRGBImage(int[] pixels, int w, int h, int pixelSize) { SampleModel sample = new SinglePixelPackedSampleModel( DataBuffer.TYPE_INT, w, h, new int[] { 0xFF0000, 0x00FF00, 0x0000FF }); DataBufferInt dataBuffer = new DataBufferInt(pixels, pixelSize); WritableRaster raster = Raster.createWritableRaster(sample, dataBuffer, new Point(0, 0)); return new BufferedImage(COLOR_MODEL_RGB, raster, true, null); } /** * 生成对应指定像素的ARGB模式BufferedImage * * @param pixels * @param w * @param h * @param pixelSize * @return */ public static BufferedImage newAwtARGBImage(int[] pixels, int w, int h, int pixelSize) { DataBuffer dataBuffer = new DataBufferInt(pixels, pixelSize); SampleModel sample = new SinglePixelPackedSampleModel( DataBuffer.TYPE_INT, w, h, new int[] { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }); WritableRaster raster = Raster.createWritableRaster(sample, dataBuffer, new Point(0, 0)); return new BufferedImage(COLOR_MODEL_ARGB, raster, true, null); } public static BufferedImage copy(BufferedImage image, int type) { if (image == null) { throw new RuntimeException("Image is null !"); } int width = image.getWidth(); int height = image.getHeight(); BufferedImage img = new BufferedImage(width, height, type); Graphics g = img.createGraphics(); g.drawImage(image, 0, 0, null); g.dispose(); if (image != null) { image.flush(); image = null; } return img; } /** * 创建指定数量的BufferedImage * * @param count * @param w * @param h * @param transparency * @return */ public static BufferedImage[] createImage(int count, int w, int h, int transparency) { BufferedImage[] image = new BufferedImage[count]; for (int i = 0; i < image.length; i++) { image[i] = JavaSEGraphicsUtils.createImage(w, h, transparency); } return image; } /** * 以指定位置、指定大小填充指定颜色 * * @param g * @param x * @param y * @param width * @param height * @param color */ public static void rectFill(Graphics g, int x, int y, int width, int height, Color color) { g.setColor(color); g.fillRect(x, y, width, height); } /** * 以指定位置、指定大小绘制指定矩形 * * @param g * @param x * @param y * @param width * @param height * @param color */ public static void rectDraw(Graphics g, int x, int y, int width, int height, Color color) { g.setColor(color); g.drawRect(x, y, width, height); } /** * 以指定位置、指定大小绘制指定椭圆形 * * @param g * @param x * @param y * @param width * @param height * @param color */ public static void rectOval(Graphics g, int x, int y, int width, int height, Color color) { g.setColor(color); g.drawOval(x, y, width, height); g.fillOval(x, y, width, height); } /** * 返回一个实例化的字体 * * @return */ public static Font getFont() { return getFont(LSystem.FONT_NAME, LSystem.FONT_TYPE); } /** * 返回一个实例化的字体 * * @param size * @return */ public static Font getFont(int size) { return getFont(LSystem.FONT_NAME, size); } /** * 返回一个实例化的字体 * * @param fontName * @param size * @return */ public static Font getFont(String fontName, int size) { return getFont(fontName, 0, size); } /** * 返回一个实例化的字体 * * @param fontName * @param style * @param size * @return */ public static Font getFont(String fontName, int style, int size) { return new Font(fontName, style, size); } /** * 以突出样式绘制指定文字信息 * * @param graphics * @param message * @param i * @param j * @param color * @param color1 */ public static void drawStyleString(final Graphics graphics, final String message, final int x, final int y, final Color color, final Color color1) { graphics.setColor(color); graphics.drawString(message, x + 1, y); graphics.drawString(message, x - 1, y); graphics.drawString(message, x, y + 1); graphics.drawString(message, x, y - 1); graphics.setColor(color1); graphics.drawString(message, x, y); } /** * 绘制六芒星 * * @param g * @param color * @param x * @param y * @param r */ public static void drawSixStart(Graphics g, Color color, int x, int y, int r) { g.setColor(color); drawTriangle(g, color, x, y, r); drawRTriangle(g, color, x, y, r); } /** * 绘制正三角 * * @param g * @param color * @param x * @param y * @param r */ public static void drawTriangle(Graphics g, Color color, int x, int y, int r) { int x1 = x; int y1 = y - r; int x2 = x - (int) (r * Math.cos(Math.PI / 6)); int y2 = y + (int) (r * Math.sin(Math.PI / 6)); int x3 = x + (int) (r * Math.cos(Math.PI / 6)); int y3 = y + (int) (r * Math.sin(Math.PI / 6)); int[] xpos = new int[3]; xpos[0] = x1; xpos[1] = x2; xpos[2] = x3; int[] ypos = new int[3]; ypos[0] = y1; ypos[1] = y2; ypos[2] = y3; g.setColor(color); g.fillPolygon(xpos, ypos, 3); } /** * 绘制倒三角 * * @param g * @param color * @param x * @param y * @param r */ public static void drawRTriangle(Graphics g, Color color, int x, int y, int r) { int x1 = x; int y1 = y + r; int x2 = x - (int) (r * Math.cos(Math.PI / 6.0)); int y2 = y - (int) (r * Math.sin(Math.PI / 6.0)); int x3 = x + (int) (r * Math.cos(Math.PI / 6.0)); int y3 = y - (int) (r * Math.sin(Math.PI / 6.0)); int[] xpos = new int[3]; xpos[0] = x1; xpos[1] = x2; xpos[2] = x3; int[] ypos = new int[3]; ypos[0] = y1; ypos[1] = y2; ypos[2] = y3; g.setColor(color); g.fillPolygon(xpos, ypos, 3); } /** * copy指定图像到目标图形中 * * @param target * @param source * @return */ public static BufferedImage copy(BufferedImage target, Image source) { Graphics2D g = target.createGraphics(); g.drawImage(source, 0, 0, null); g.dispose(); return target; } public static BufferedImage copy(BufferedImage target, BufferedImage source) { Graphics2D g = target.createGraphics(); g.drawImage(source, 0, 0, null); g.dispose(); return target; } public static Image copy(Image target, BufferedImage source) { Graphics2D g = JavaSEGraphicsUtils.getBufferImage(target) .createGraphics(); g.drawImage(source, 0, 0, null); g.dispose(); return target; } public static Image copy(Image target, Image source) { Graphics g = JavaSEGraphicsUtils.getBufferImage(target).getGraphics(); g.drawImage(source, 0, 0, null); g.dispose(); return target; } /** * 获得一个Image对像的ColorModel * * @param image * @return */ public static ColorModel getColorModel(Image image) { try { PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false); pg.grabPixels(); return pg.getColorModel(); } catch (InterruptedException e) { throw new RuntimeException(e); } } /** * 生成一个BufferImage * * @param w * @param h * @param flag * @return */ final static public BufferedImage createImage(int w, int h, boolean flag) { if (flag) { return new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR_PRE); } else { return new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); } } final static public BufferedImage createIntdexedImage(int w, int h) { return new BufferedImage(w, h, BufferedImage.TYPE_BYTE_INDEXED); } /** * 创建一个指定颜色的图形按钮 * * @param color * @param flag * @param w * @param h * @return */ public static BufferedImage createButtonImage(Color color, boolean flag, int w, int h) { BufferedImage bufferedimage = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); Graphics2D graphics2d = bufferedimage.createGraphics(); Color color1 = (color = flag ? color.brighter() : color).brighter(); GradientPaint gradientpaint = new GradientPaint(0, 0, color, w / 2 + 2, h / 2 + 2, color1); graphics2d.setPaint(gradientpaint); graphics2d.fillRect(2, 2, w - 4, h - 4); graphics2d.setColor(Color.BLACK); graphics2d.drawLine(1, h - 3, 1, 1); graphics2d.drawLine(1, 1, w - 3, 1); graphics2d.setColor(Color.BLACK); graphics2d.drawLine(0, h - 1, w - 1, h - 1); graphics2d.drawLine(w - 1, h - 1, w - 1, 0); graphics2d.setColor(Color.BLACK); graphics2d.drawRect(0, 0, w - 2, h - 2); graphics2d.dispose(); graphics2d = null; return bufferedimage; } /** * 创建一幅按钮用背景图 * * @param w * @param h * @param color1 * @param color2 * @return */ public static BufferedImage createButtonBackground(int w, int h, Color color1, Color color2) { BufferedImage image = JavaSEGraphicsUtils.createImage(w, h, false); Graphics2D g = image.createGraphics(); GradientPaint gradientpaint = new GradientPaint(0, 0, color1, w / 2, h, color2); g.setPaint(gradientpaint); g.fillRect(2, 2, w - 4, h - 4); g.setColor(Color.BLACK); g.drawLine(1, h - 3, 1, 1); g.drawLine(1, 1, w - 3, 1); g.setColor(Color.BLACK); g.drawLine(0, h - 1, w - 1, h - 1); g.drawLine(w - 1, h - 1, w - 1, 0); g.setColor(Color.BLACK); g.drawRect(0, 0, w - 2, h - 2); g.dispose(); g = null; return image; } /** * 创建一个指定透明度的BufferedImage * * @param width * @param height * @param transparency * @return */ public static BufferedImage createImage(int width, int height, int type) { return new BufferedImage(width, height, type); } /** * 将指定像素集合(int[]格式)转为BufferedImage * * @param data * @return */ final static public BufferedImage getImage(int[] data) { if (data == null || data.length < 3 || data[0] < 1 || data[1] < 1) { return null; } int width = data[0]; int height = data[1]; if (data.length < 2 + width * height) { return null; } BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { image.setRGB(j, i, data[2 + j + i * width]); } } return image; } /** * 变更指定BufferedImage大小 * * @param image * @param w * @param h * @return */ public static BufferedImage getResize(BufferedImage image, int w, int h) { int width = image.getWidth(), height = image.getHeight(); if (width == w && height == h) { return image; } BufferedImage img; AffineTransform tx = new AffineTransform(); tx.scale((double) w / width, (double) h / height); AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); img = op.filter(image, null); return img; } /** * 获得一组序号连续的图片 * * @param fileName * @param range * (指定图片范围,如("1-2")) * @return */ public static Image[] loadSequenceImages(String fileName, String range) { try { int start_range = -1; int end_range = -1; int images_count = 1; int minusIndex = range.indexOf('-'); if ((minusIndex > 0) && (minusIndex < (range.length() - 1))) { try { start_range = Integer.parseInt(range.substring(0, minusIndex)); end_range = Integer.parseInt(range .substring(minusIndex + 1)); if (start_range < end_range) { images_count = end_range - start_range + 1; } } catch (Exception ex) { ex.printStackTrace(); } } Image[] images = new Image[images_count]; for (int i = 0; i < images_count; i++) { String imageName = fileName; if (images_count > 1) { int dotIndex = fileName.lastIndexOf('.'); if (dotIndex >= 0) { imageName = fileName.substring(0, dotIndex) + (start_range + i) + fileName.substring(dotIndex); } } images[i] = JavaSEGraphicsUtils.loadImage(imageName); } return images; } catch (Exception ex) { ex.printStackTrace(); } return null; } /** * 匹配图片到设定大小的图片之上 * * @param image * @param w * @param h * @return */ public static BufferedImage matchBufferedImage(BufferedImage image, int w, int h) { BufferedImage result = null; Graphics2D graphics2d; (graphics2d = (result = JavaSEGraphicsUtils.createImage(w, h, true)) .createGraphics()).setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); graphics2d.drawImage(image, 0, 0, null); graphics2d.dispose(); graphics2d = null; return result; } /** * 变更指定Image大小 * * @param image * @param w * @param h * @return */ public static Image getResize(Image image, int w, int h) { if (image == null) { return null; } if (image.getWidth(null) == w && image.getHeight(null) == h) { return image; } BufferedImage result = null; Graphics2D graphics2d; (graphics2d = (result = JavaSEGraphicsUtils.createImage(w, h, true)) .createGraphics()).setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); graphics2d.drawImage(image, 0, 0, w, h, 0, 0, image.getWidth(null), image.getHeight(null), null); graphics2d.dispose(); graphics2d = null; return result; } // 文字清晰过滤开 final static private RenderingHints VALUE_TEXT_ANTIALIAS_ON = new RenderingHints( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); // 文字清晰过滤关 final static private RenderingHints VALUE_TEXT_ANTIALIAS_OFF = new RenderingHints( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); // 清晰过滤开 final static private RenderingHints VALUE_ANTIALIAS_ON = new RenderingHints( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 清晰过滤关 final static private RenderingHints VALUE_ANTIALIAS_OFF = new RenderingHints( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); /** * 设定图像解析度 * * @param g * @param smooth * @param antialiasing */ public static void setRenderingHints(Graphics g, boolean smooth, boolean antialiasing) { if (smooth) { ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); } else { ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); } if (antialiasing) { ((Graphics2D) g).setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); } else { ((Graphics2D) g).setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); } } /** * 设定文字是否抗锯齿 * * @param g * @param flag */ public static void setAntialias(Graphics g, boolean flag) { if (flag) { ((Graphics2D) g).setRenderingHints(VALUE_TEXT_ANTIALIAS_ON); } else { ((Graphics2D) g).setRenderingHints(VALUE_TEXT_ANTIALIAS_OFF); } } /** * 设定全局抗锯齿 * * @param g * @param flag */ public static void setAntialiasAll(Graphics g, boolean flag) { if (flag) { ((Graphics2D) g).setRenderingHints(VALUE_ANTIALIAS_ON); } else { ((Graphics2D) g).setRenderingHints(VALUE_ANTIALIAS_OFF); } } /** * 剪切指定图像 * * @param image * @param objectWidth * @param objectHeight * @param x1 * @param y1 * @param x2 * @param y2 * @return */ public static BufferedImage drawClipImage(final Image image, int objectWidth, int objectHeight, int x1, int y1, int x2, int y2) { BufferedImage buffer = JavaSEGraphicsUtils.createImage(objectWidth, objectHeight, true); Graphics g = buffer.getGraphics(); Graphics2D graphics2D = (Graphics2D) g; graphics2D.drawImage(image, 0, 0, objectWidth, objectHeight, x1, y1, x2, y2, null); graphics2D.dispose(); graphics2D = null; return buffer; } /** * 剪切指定图像 * * @param image * @param objectWidth * @param objectHeight * @param x * @param y * @return */ public static BufferedImage drawClipImage(final Image image, int objectWidth, int objectHeight, int x, int y) { BufferedImage buffer = JavaSEGraphicsUtils.createImage(objectWidth, objectHeight, true); Graphics2D graphics2D = buffer.createGraphics(); graphics2D.drawImage(image, 0, 0, objectWidth, objectHeight, x, y, x + objectWidth, objectHeight + y, null); graphics2D.dispose(); graphics2D = null; return buffer; } /** * 剪切指定图像 * * @param image * @param x * @param y * @param objectWidth * @param objectHeight * @return */ public static BufferedImage drawCropImage(final Image image, int x, int y, int objectWidth, int objectHeight) { BufferedImage buffer = JavaSEGraphicsUtils.createImage(objectWidth, objectHeight, true); Graphics2D graphics2D = buffer.createGraphics(); graphics2D.drawImage(image, 0, 0, objectWidth, objectHeight, x, y, x + objectWidth, objectHeight + y, null); graphics2D.dispose(); graphics2D = null; return buffer; } /** * 水平翻转当前图像 * * @return */ public static BufferedImage rotateImage(final BufferedImage image) { int w = image.getWidth(); int h = image.getHeight(); BufferedImage img; Graphics2D graphics2d; (graphics2d = (img = new BufferedImage(w, h, image.getColorModel() .getTransparency())).createGraphics()).drawImage(image, 0, 0, w, h, w, 0, 0, h, null); graphics2d.dispose(); return img; } /** * 水平翻转当前图像 * * @param image * @return */ public static BufferedImage rotateImage(final Image image) { return JavaSEGraphicsUtils.rotateImage(JavaSEGraphicsUtils .getBufferImage(image)); } public static BufferedImage rotateImage(final BufferedImage image, final int degrees) { AffineTransform at = new AffineTransform(); at.rotate( degrees < 0 ? -Math.toRadians(degrees) : Math .toRadians(degrees), image.getWidth() / 2, image .getHeight() / 2); BufferedImageOp bio = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR); BufferedImage dest = bio.filter(image, null); return dest; } /** * 设定画布呈相方式为低劣 * * @param g */ public static void setPoorRenderingHints(final Graphics2D g) { g.addRenderingHints(hints_poor); } /** * 设定画布呈相方式为优秀 * * @param g */ public static void setExcellentRenderingHints(final Graphics2D g) { g.addRenderingHints(hints_excellent); } /** * 设定画布呈相方式为一般 * * @param g */ public static void setGeneralRenderingHints(final Graphics2D g) { g.addRenderingHints(hints_general); } /** * 将Image转为BufferImage * * @param image * @return */ public static BufferedImage getBufferImage(Image image) { if (image == null) { return null; } if (image instanceof BufferedImage) { return (BufferedImage) image; } boolean isOpaque = true; int w = image.getWidth(null); int h = image.getHeight(null); PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, true); if ((w > 48 && w < 512) || (h > 48 && h < 512)) { try { pg.grabPixels(); } catch (InterruptedException e) { e.printStackTrace(); } int pixels[] = (int[]) pg.getPixels(); int pixel; int size = w * h; for (int i = 0; i < size; i++) { pixel = LColor.premultiply(pixels[i]); if (isOpaque && (pixel >>> 24) < 255) { isOpaque = false; break; } } } else { isOpaque = !pg.getColorModel().hasAlpha(); } BufferedImage bufferimage = JavaSEGraphicsUtils.createImage(w, h, !isOpaque); Graphics g = bufferimage.createGraphics(); g.drawImage(image, 0, 0, null); g.dispose(); if (cacheImages.containsValue(image)) { Object key = null; Set entry = cacheImages.entrySet(); for (Iterator it = entry.iterator(); it.hasNext();) { Entry e = (Entry) it.next(); if (e.getValue() == image) { key = e.getKey(); } } if (key != null) { Image img = (Image) cacheImages.remove(key); if (img != null) { img.flush(); img = null; } cacheImages.put((String) key, bufferimage); } } if (image != null) { image.flush(); image = null; } pg = null; return bufferimage; } /** * 加载内部file转为Image * * @param innerFileName * @return */ final static public Image loadImage(final String innerFileName) { return JavaSEGraphicsUtils.loadImage(innerFileName, true); } /** * 加载内部file转为BufferedImage * * @param innerFileName * @return */ final static public BufferedImage loadBufferedImage(final String resName) { try { InputStream in = Resources.openResource(resName); if (in == null) { throw new RuntimeException( ("File not found. ( " + resName + " )").intern()); } return javax.imageio.ImageIO.read(in); } catch (IOException e) { throw new RuntimeException( ("File not found. ( " + resName + " )").intern()); } } /** * 加载byte[]为Image * * @param bytes * @return */ final static public Image loadImage(final byte[] bytes) { Image result = null; try { result = toolKit.createImage(bytes); waitImage(result); } catch (Exception e) { result = null; } return result; } final static public Image loadImage(final String name, final byte[] bytes) { if (cacheByteImages.size() > LSystem.DEFAULT_MAX_CACHE_SIZE) { cacheByteImages.clear(); System.gc(); } Image result = null; result = (Image) cacheByteImages.get(name); if (result == null) { try { result = toolKit.createImage(bytes); cacheByteImages.put(name, result); waitImage(result); } catch (Exception e) { result = null; } } return result; } /** * 加载内部file转为Image * * @param inputstream * @return */ final static public Image loadImage(final String innerFileName, final boolean isInner) { if (innerFileName == null) { return null; } String tmp_file = innerFileName, innerName = StringUtils .replaceIgnoreCase(innerFileName, "\\", "/"); String keyName = innerName.toLowerCase(); Object imageReference = cacheImages.get(keyName); if (imageReference == null) { int read; boolean flag; byte[] bytes = null; File file_tmp = null; Image img_tmp = null; InputStream in = null; ByteArrayOutputStream os = null; try { os = new ByteArrayOutputStream(8192); if (isInner) { in = new DataInputStream(new BufferedInputStream( Resources.openResource(innerName))); flag = true; } else { file_tmp = new File(tmp_file); flag = file_tmp.exists(); if (flag) { in = new DataInputStream(new BufferedInputStream( new FileInputStream(file_tmp))); } } if (flag) { bytes = new byte[8192]; while ((read = in.read(bytes)) >= 0) { os.write(bytes, 0, read); } bytes = os.toByteArray(); img_tmp = toolKit.createImage(bytes); } cacheImages.put(keyName, imageReference = img_tmp); waitImage(img_tmp); } catch (Exception e) { if (!isInner) { imageReference = null; } else { return loadImage(innerFileName, false); } } finally { try { if (os != null) { os.flush(); os = null; } if (in != null) { in.close(); in = null; } img_tmp = null; bytes = null; tmp_file = null; file_tmp = null; } catch (IOException e) { } } } if (imageReference == null) { throw new RuntimeException( ("File not found. ( " + innerName + " )").intern()); } return (Image) imageReference; } final static public Image loadNotCacheImage(final String innerFileName) { if (innerFileName == null) { return null; } int read; byte[] bytes = null; Image img_tmp = null; InputStream in = null; ByteArrayOutputStream os = null; try { os = new ByteArrayOutputStream(8192); in = new DataInputStream(new BufferedInputStream( Resources.openResource(innerFileName))); bytes = new byte[8192]; while ((read = in.read(bytes)) >= 0) { os.write(bytes, 0, read); } bytes = os.toByteArray(); img_tmp = toolKit.createImage(bytes); waitImage(img_tmp); } catch (Exception e) { throw new RuntimeException( ("File not found. ( " + innerFileName + " )").intern()); } finally { try { if (os != null) { os.flush(); os = null; } if (in != null) { in.close(); in = null; } bytes = null; } catch (IOException e) { } } return img_tmp; } /** * 过滤指定像素 * * @param images * @param color * @return */ public static BufferedImage filterImage(byte[] images, LColor color) { BufferedImage img = getBufferImage(JavaSEGraphicsUtils.toolKit .createImage(images)); if (img.getColorModel().hasAlpha()) { int[] srcImages = JavaSEGraphicsUtils.getPixels(img); int[] pixels = NativeSupport.toColorKey(srcImages, color.getRGB()); JavaSEGraphicsUtils.setPixels(img, pixels, img.getWidth(), img.getHeight()); } else { BufferedImage tmp = JavaSEGraphicsUtils.createImage(img.getWidth(), img.getHeight(), true); Graphics2D g = tmp.createGraphics(); g.drawImage(img, 0, 0, null); g.dispose(); int[] srcImages = JavaSEGraphicsUtils.getPixels(tmp); int[] pixels = NativeSupport.toColorKey(srcImages, color.getRGB()); JavaSEGraphicsUtils.setPixels(tmp, pixels, img.getWidth(), img.getHeight()); if (img != null) { img.flush(); img = null; } img = tmp; } return img; } /** * 过滤指定像素 * * @param images * @param color * @return */ public static BufferedImage filterImage(byte[] images, int[] colors) { BufferedImage img = getBufferImage(JavaSEGraphicsUtils.toolKit .createImage(images)); if (img.getColorModel().hasAlpha()) { int[] srcImages = JavaSEGraphicsUtils.getPixels(img); int[] pixels = NativeSupport.toColorKeys(srcImages, colors); JavaSEGraphicsUtils.setPixels(img, pixels, img.getWidth(), img.getHeight()); } else { BufferedImage tmp = JavaSEGraphicsUtils.createImage(img.getWidth(), img.getHeight(), true); Graphics2D g = tmp.createGraphics(); g.drawImage(img, 0, 0, null); g.dispose(); int[] srcImages = JavaSEGraphicsUtils.getPixels(tmp); int[] pixels = NativeSupport.toColorKeys(srcImages, colors); JavaSEGraphicsUtils.setPixels(tmp, pixels, img.getWidth(), img.getHeight()); if (img != null) { img.flush(); img = null; } img = tmp; } return img; } private static Panel context = new Panel(); /** * 同步图像文件 * * @param image */ public static void waitImage(Image image) { if (image == null) { return; } if (image instanceof BufferedImage) { return; } MediaTracker mediaTracker = null; try { if (context != null) { mediaTracker = new MediaTracker(context); mediaTracker.addImage(image, 0); if ((mediaTracker.statusID(0, true) & MediaTracker.ERRORED) != 0) { throw new Exception(); } } } catch (Exception e) { if (mediaTracker != null) { mediaTracker.removeImage(image, 0); mediaTracker = null; } } waitImage(100, image); } /** * 延迟加载image,以使其同步。 * * @param delay * @param image */ private static void waitImage(int delay, Image image) { try { for (int i = 0; i < delay; i++) { if (toolKit.prepareImage(image, -1, -1, null)) { return; } Thread.sleep(delay); } } catch (Exception e) { } } /** * 透明度设定 * * @param g * @param d */ final static public void setAlpha(Graphics g, double d) { AlphaComposite alphacomposite = AlphaComposite .getInstance(3, (float) d); ((Graphics2D) g).setComposite(alphacomposite); } /** * 透明度设定 * * @param g2d * @param d */ final static public void setAlpha(Graphics2D g2d, double d) { AlphaComposite alphacomposite = AlphaComposite .getInstance(3, (float) d); g2d.setComposite(alphacomposite); } /** * 返回当前画布透明度 * * @param g2d * @return */ final static public float getAlpha(Graphics2D g2d) { return ((AlphaComposite) g2d.getComposite()).getAlpha(); } /** * 生成BufferedImage的hash序列 * * @param BufferedImage * @return */ public static int hashImage(BufferedImage img) { int hash_result = 0; hash_result = (hash_result << 7) ^ img.getHeight(null); hash_result = (hash_result << 7) ^ img.getWidth(null); for (int pixel = 0; pixel < 20; ++pixel) { int x = (pixel * 50) % img.getWidth(null); int y = (pixel * 100) % img.getHeight(null); hash_result = (hash_result << 7) ^ img.getRGB(x, y); } return hash_result; } /** * 生成Image的hash序列 * * @param img * @return */ public static int hashImage(Image img) { int hash_result = 0; int width = img.getWidth(null); int height = img.getHeight(null); hash_result = (hash_result << 7) ^ height; hash_result = (hash_result << 7) ^ width; PixelGrabber pg = new PixelGrabber(img, 0, 0, width, height, true); try { pg.grabPixels(); } catch (InterruptedException e) { e.printStackTrace(); } int pixels[] = (int[]) pg.getPixels(); for (int pixel = 0; pixel < 20; ++pixel) { int x = (pixel * 50) % width; int y = (pixel * 100) % height; hash_result = (hash_result << 7) ^ pixels[x + width * y]; } return hash_result; } public static void setPixels(BufferedImage img, int[] pixels, int width, int height) { img.setRGB(0, 0, width, height, pixels, 0, width); } /** * 从一个单独的BufferedImage中获得其像素信息 * * @param img * @return */ public static int[] getPixels(final BufferedImage img) { int width = img.getWidth(); int height = img.getHeight(); int pixels[] = new int[width * height]; img.getRGB(0, 0, width, height, pixels, 0, width); return pixels; } /** * 从一个单独的BufferedImage中获得其像素信息 * * @param img * @return */ public static byte[] getBytePixels(final BufferedImage img) { if (img == null) { return null; } DataBuffer buffer = img.getRaster().getDataBuffer(); switch (buffer.getDataType()) { case DataBuffer.TYPE_BYTE: DataBufferByte byteBuf = (DataBufferByte) buffer; return byteBuf.getData(); default: BufferedImage tmp = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_4BYTE_ABGR); Graphics2D g = tmp.createGraphics(); g.drawImage(img, 0, 0, null); g.dispose(); buffer = img.getRaster().getDataBuffer(); if (buffer.getDataType() == DataBuffer.TYPE_BYTE) { return ((DataBufferByte) buffer).getData(); } return null; } } /** * 清空image缓存 * */ final static public void destroyImages() { cacheImages.clear(); System.gc(); } }