import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;
import com.sun.image.codec.jpeg.*;
import java.awt.font.*;
import java.awt.geom.*;

public class RenderJ {
	private BufferedImage bi;
	private Graphics2D g;

	public RenderJ(int width, int height){
		bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
		g = bi.createGraphics();
        g.fillRect(0, 0, width, height);
        g.setBackground(Color.WHITE);
        g.setColor(Color.BLACK);
        // Enable antialiasing for shapes
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
        g.setFont(new Font("TimesRoman", Font.PLAIN, 10));
	}

	public static void main(String[] args) throws Exception{
		RenderJ c = new RenderJ(200, 200);
        c.setColor(Color.RED);
        c.drawLine(10,10,180,180);
        c.setColor(Color.BLACK);
		c.drawString("TOP",10,100);
        //c.g.transform(new AffineTransform(0.98480775301220802, 0.17364817766693033, -0.17364817766693033, 0.98480775301220802, 0.0, 0.0));

        c.transform(new AffineTransform(0.8*0.98480775301220802, 0.8*0.17364817766693033, 0.8*-0.17364817766693033, 0.8*0.98480775301220802, 0.0, 5.0));
        c.setColor(Color.BLUE);
        c.drawLine(10,10,180,180);

        c.setColor(Color.RED);
		c.drawString("TOP",10,30);

		c.writeGIF("C:\\tmp\\buffImg1.gif");
        c.writeBitmap("C:\\tmp\\buffImg1.txt", true);
	}

	private BufferedImage invert(BufferedImage bi){
		BufferedImage bi1 = new BufferedImage(bi.getWidth(), bi.getHeight(), bi.getType());
		DataBuffer db = bi.getRaster().getDataBuffer();
		DataBuffer db1 = bi1.getRaster().getDataBuffer();

		int width = bi.getWidth()*3;
		int height = bi.getHeight();
		int jf = 0;
		int jr = (height-1) * width;
		//System.out.println("width*height="+width*height);
		//System.out.println("db.getSize="+db.getSize());
		for(int i=0;i<height;i++,jf+=width,jr-=width){
			for(int j=0;j<width;j++){
				db1.setElem(j+jr, db.getElem(j+jf));
			}
		}
		return bi1;
	}

	public void writePNG(String outFile) throws Exception{
		ImageIO.write(invert(bi), "png", new File(outFile));
	}

	public void writeJPG(String outFile) throws Exception{
		ImageIO.write(invert(bi), "jpg", new File(outFile));
	}

	public void writeGIF(String outFile) throws Exception{
		new GIFEncoder(invert(bi)).write(new FileOutputStream(outFile));
	}

	public void writeBitmap(String outFile, boolean textArt) throws Exception{
		int width = bi.getWidth(null);
		int height = bi.getHeight(null);
		int[] pixels = new int[width*height];
		new PixelGrabber(invert(bi), 0, 0, width, height, pixels, 0, width).grabPixels();
		FileOutputStream fout = new FileOutputStream(outFile);
		for(int i=0;i<pixels.length;i++){
			fout.write(pixels[i]);
			if((textArt)&&(i%width == width-1)){
				fout.write(13);
				fout.write(10);
			}
		}
		fout.close();
	}

	public void setColor(Color c){
		g.setColor(c);
	}

    public void transform(AffineTransform tx){
        g.transform(tx);
    }
    
	public void translate(int x, int y){
		g.translate(x, y);
	}

	public void drawLine(int x1, int y1, int x2, int y2){
		g.drawLine(x1, y1, x2, y2);
	}

	public void drawString(String s, double x, double y){
        AffineTransform old = g.getTransform();
        AffineTransform delta = new AffineTransform(1.0, 0.0, 0.0, -1.0, x, y);
        AffineTransform newt = ((AffineTransform)old.clone());
        newt.concatenate(delta);
        g.setTransform(newt);
        g.drawString(s, 0, 0);
        g.setTransform(old);
	}

}