package br.com.etyllica.layer; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.awt.image.DataBufferByte; import java.awt.image.DataBufferInt; import java.awt.image.Raster; import br.com.etyllica.awt.SVGColor; import br.com.etyllica.core.collision.CollisionDetector; import br.com.etyllica.core.graphics.Graphics; import br.com.etyllica.loader.image.ImageLoader; /** * * @author yuripourre * */ public class BufferedLayer extends ImageLayer { protected Graphics2D graphics; protected BufferedImage originalBuffer; protected BufferedImage buffer; private static int MAX_INT = 0xff; /** * * @param x * @param y */ public BufferedLayer(int x, int y) { super(x,y); } /** * * @param x * @param y * @param path */ public BufferedLayer(int x, int y, String path) { super(x,y,path); copy(ImageLoader.getInstance().getImage(path)); } /** * * @param x * @param y * @param path * @param absolute */ public BufferedLayer(int x, int y, String path, boolean absolute) { super(x,y,path, absolute); copy(ImageLoader.getInstance().getImage(path, absolute)); } /** * * @param path */ public BufferedLayer(String path) { this(0,0,path); } /** * * @param x * @param y * @param buffer */ public BufferedLayer(int x, int y, BufferedImage buffer) { super(x,y); this.w = buffer.getWidth(); this.h = buffer.getHeight(); copy(buffer); } /** * * @param x * @param y * @param w * @param h */ public BufferedLayer(int x, int y, int w, int h) { this(x,y); this.w = w; this.h = h; originalBuffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); buffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); clearGraphics(); } /** * * @param x * @param y * @param w * @param h * @param imageData - Data as byteArray */ public BufferedLayer(int x, int y, int w, int h, byte[] imageData) { this(x,y); this.w = w; this.h = h; originalBuffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); createBuffer(imageData); } /** * * @param buffer */ public BufferedLayer(BufferedImage buffer) { this(0,0,buffer); } /** * * @param buffer */ public void copy(Image buffer) { if(buffer==null) return; int w = buffer.getWidth(null); int h = buffer.getHeight(null); this.w = w; this.h = h; this.originalBuffer = new BufferedImage(w, h,BufferedImage.TYPE_INT_ARGB); this.graphics = originalBuffer.createGraphics(); graphics.drawImage(buffer, 0, 0, null); resetImage(); } /** * * @param buffer */ public void copy(BufferedImage buffer) { this.originalBuffer = new BufferedImage((int)w, (int)h,BufferedImage.TYPE_INT_ARGB); this.originalBuffer.getGraphics().drawImage(buffer,0,0,null); w = buffer.getWidth(); h = buffer.getHeight(); resetImage(); } public void cropImage(int xImage, int yImage, int w, int h ) { buffer = new BufferedImage(w, h,BufferedImage.TYPE_INT_ARGB); graphics = buffer.createGraphics(); graphics.drawImage(originalBuffer, -xImage, -yImage, null); this.w = w; this.h = h; } /** * ImagemBuffer back to original state */ public void resetImage() { buffer = new BufferedImage(w, h,BufferedImage.TYPE_INT_ARGB); graphics = buffer.createGraphics(); graphics.drawImage(originalBuffer, 0, 0, null); } public Graphics2D clearGraphics() { Graphics2D g2 = originalBuffer.createGraphics(); g2.setColor(SVGColor.TRANSPARENT); g2.clearRect(x, y, w, h); graphics = buffer.createGraphics(); graphics.setBackground(new Color(MAX_INT, MAX_INT, MAX_INT, 0)); graphics.clearRect(0, 0, w, h); return graphics; } public void refresh() { buffer.getGraphics().drawImage(originalBuffer, 0, 0, null); } /** * Offset all pixels to the selected value * Image receive color * * @param red * @param green * @param blue */ public void offsetRGB(int red, int green, int blue) { resetImage(); offsetPixels(red,green,blue); } public void offsetNegativeRed(int red) { resetImage(); offsetPixels(0, -red, -red); } public void offsetNegativeGreen(int green) { resetImage(); offsetPixels(-green, 0, -green); } public void offsetNegativeBlue(int blue) { resetImage(); offsetPixels(-blue, -blue, 0); } private void offsetPixels(int offsetRed, int offsetGreen, int offsetBlue) { for(int j=0;j<h;j++) { for(int i=0;i<w;i++) { //Pego o rgb do pixel selecionado int rgb = originalBuffer.getRGB(i,j); int a = (rgb>>24) & 0xff; int r = ((rgb & 0x00ff0000) >> 16); int g = ((rgb & 0x0000ff00) >> 8); int b = ((rgb & 0x000000ff) >> 0); //O valor de offset é somado nos valores de rgb, logo //se o offset for positivo, as cores escuras tornam-se claras(coloridas) e o branco nao se altera. //se o offset for negativo, as cores claras(recebem a cor negativa desejada) e o preto nao se altera. r += offsetRed; g += offsetGreen; b += offsetBlue; //Verify pixel range 0~255 if(r>MAX_INT) { r = MAX_INT; }else if(r<0) { r = 0; } //Verify pixel range 0~255 if(g>MAX_INT) { g = MAX_INT; }else if(g<0) { g = 0; } //Verify pixel range 0~255 if(b>MAX_INT) { b = MAX_INT; }else if(b<0) { b = 0; } buffer.setRGB(i, j, new Color(r,g,b,a).getRGB()); } } } //Image Manipulation public void flipVertical() { AffineTransform tx = AffineTransform.getScaleInstance(1, -1); tx.translate(0, -h); AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); buffer = op.filter(buffer, null); } public void flipHorizontal() { AffineTransform tx = AffineTransform.getScaleInstance(-1, 1); tx.translate(-w, 0); AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); buffer = op.filter(buffer, null); } public void resize(int width, int height) { double scaleW = (double)width/(double)originalBuffer.getWidth(); double scaleH = (double)height/(double)originalBuffer.getHeight(); AffineTransform transform = AffineTransform.getScaleInstance(scaleW, scaleH); AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); buffer = op.filter(buffer, null); this.w = width; this.h = height; } public void girar180() { AffineTransform tx = AffineTransform.getScaleInstance(-1, -1); tx.translate(-w, -h); AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); buffer = op.filter(buffer, null); } public byte[][][] getBytes() { DataBufferInt db = (DataBufferInt)buffer.getRaster().getDataBuffer(); int[] by = db.getData(); byte pixels[][][] = new byte[w][h][3]; for(int j=0;j<h;j++) { for(int i=0;i<w;i++) { int rgb = by[i+j*w]; byte r = (byte) ((rgb & 0x00ff0000) >> 16); byte g = (byte) ((rgb & 0x0000ff00) >> 8); byte b = (byte) (rgb & 0x000000ff); pixels[i][j][0] = r; pixels[i][j][1] = g; pixels[i][j][2] = b; } } return pixels; } public void setBuffer(BufferedImage image) { this.originalBuffer = image; this.w = image.getWidth(); this.h = image.getHeight(); resetImage(); } public BufferedImage getBuffer() { return buffer; } public boolean colideAlphaPoint(int px, int py) { if(CollisionDetector.colideRectPoint(this, px, py)) { int mx = px-x; int my = py-y; if(mx>=buffer.getWidth()||my>=buffer.getHeight()) { return false; } Color color = new Color(buffer.getRGB(mx, my), true); return color.getAlpha() == MAX_INT; } return false; } public Color getColorPoint(int px, int py) { if(CollisionDetector.colideRectPoint(this, px, py)) { int mx = px-x; int my = py-y; if(mx>=buffer.getWidth() || my>=buffer.getHeight()) { return null; } Color color = new Color(buffer.getRGB(mx, my), true); return color; } return null; } public Graphics2D getGraphics() { return graphics; } @Override public void simpleDraw(Graphics g, int x, int y) { g.drawImage( buffer, x, y, x+w,y+h, xImage,yImage,xImage+w,yImage+h, null ); } public void createBuffer(byte[] imageData) { DataBufferByte dataBuffer = new DataBufferByte(imageData, imageData.length); originalBuffer.setData(Raster.createRaster(originalBuffer.getSampleModel(), dataBuffer, null)); resetImage(); } }