package com.kreative.paint.util; import java.awt.Cursor; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Paint; import java.awt.PaintContext; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.Raster; import java.util.Arrays; public class Bitmap { private int width, height; private int[] pixels; private Cursor cursorCache; public Bitmap(int width, int height, int[] pixels) { this.width = width; this.height = height; this.pixels = pixels; this.cursorCache = null; } public Bitmap(Image i) { BufferedImage bi = ImageUtils.toBufferedImage(i, false); this.width = bi.getWidth(); this.height = bi.getHeight(); this.pixels = new int[this.width * this.height]; bi.getRGB(0, 0, this.width, this.height, this.pixels, 0, this.width); this.cursorCache = null; } public int getWidth() { return width; } public int getHeight() { return height; } public int getRGB(int x, int y) { return pixels[y*width + x]; } public int[] getRGB() { int[] rgb = new int[pixels.length]; for (int i = 0; i < pixels.length; i++) rgb[i] = pixels[i]; return rgb; } public int[] getRGB(int x, int y, int w, int h, int[] rgb, int offset, int scan) { if (rgb == null) { rgb = new int[offset+h*scan]; } for (int dy = offset, sy = y*width+x, iy = 0; iy < h; dy += scan, sy += width, iy++) { for (int dx = dy, sx = sy, ix = 0; ix < w; dx++, sx++, ix++) { rgb[dx] = pixels[sx]; } } return rgb; } public BufferedImage getImage() { BufferedImage i = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); i.setRGB(0, 0, width, height, pixels, 0, width); return i; } public Cursor getCursor() { if (cursorCache == null) { BufferedImage ci = new BufferedImage(width+2, height+2, BufferedImage.TYPE_INT_ARGB); int[] ca = new int[(width+2) * (height+2)]; for (int sy = 0, dy = width+2, y = 0; y < height; sy += width, dy += width+2, y++) { for (int sx = sy, dx = dy+1, x = 0; x < width; sx++, dx++, x++) { if (pixels[sx] < 0 || pixels[sx] >= 0x01000000) { ca[dx] = (((pixels[sx] >>> 24) ^ 0xFF) * 0x010101) | 0xFF000000; } } } for (int i = width+3; i < ca.length-width-3; i++) { if (ca[i] < 0 || ca[i] >= 0x01000000) { if (ca[i-1] >= 0 && ca[i-1] < 0x01000000) ca[i-1] = 0xBECC1E; if (ca[i+1] >= 0 && ca[i+1] < 0x01000000) ca[i+1] = 0xBECC1E; if (ca[i-width-2] >= 0 && ca[i-width-2] < 0x01000000) ca[i-width-2] = 0xBECC1E; if (ca[i+width+2] >= 0 && ca[i+width+2] < 0x01000000) ca[i+width+2] = 0xBECC1E; } } for (int i = 0; i < ca.length; i++) { if (ca[i] == 0xBECC1E) ca[i] = -1; } ci.setRGB(0, 0, width+2, height+2, ca, 0, width+2); cursorCache = CursorUtils.makeCursor(ci, (width+2)/2, (height+2)/2, "-bitmap-"+Integer.toHexString(super.hashCode())+"-"); } return cursorCache; } public void paint(Graphics2D g, int x, int y) { Paint p = g.getPaint(); RenderingHints h = g.getRenderingHints(); AffineTransform t = g.getTransform(); Rectangle b = new Rectangle(x, y, width, height); PaintContext pc = p.createContext(null, b, b, t, h); ColorModel cm = pc.getColorModel(); Raster r = pc.getRaster(x, y, width, height); BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); int[] rgb = new int[width * height]; for (int iy = 0, i = 0; iy < height; iy++) { for (int ix = 0; ix < width; ix++, i++) { rgb[i] = cm.getRGB(r.getDataElements(ix, iy, null)); rgb[i] = (rgb[i] & 0xFFFFFF) | (((rgb[i] >>> 24) * (pixels[i] >>> 24) / 255) << 24); } } img.setRGB(0, 0, width, height, rgb, 0, width); g.drawImage(img, null, x, y); } public int hashCode() { return width ^ height ^ Arrays.hashCode(pixels); } public boolean equals(Object o) { if (o instanceof Bitmap) { Bitmap other = (Bitmap)o; return (this.width == other.width && this.height == other.height && Arrays.equals(this.pixels, other.pixels)); } else { return false; } } public String toString() { return "com.kreative.paint.util.Bitmap["+width+","+height+"]"; } }