⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asciidrawpanel.java

📁 ASCII图画分类: 图像处理 可以将鼠标画的图象转成ASCII的形式
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package joeh.asciidraw;
import java.awt.*;
import java.applet.*;
import java.util.*;
import java.io.*;


//We just paint on the Panel directly.
public class AsciiDrawPanel extends Panel {
	int columns;
	int rows;
	//Canvas drawArea;  //where the drawing takes place
	Image im2;
	Dimension im2s;
	Graphics im2g;
	Graphics ourG;
	File destFile;
	FileOutputStream destination = null;

	Hashtable positions;
	Vector keys;
	boolean first = true;
	Dimension recentSize = new Dimension(0,0);

	String THEchar = " ";
	Color THEcolor = Color.white;
	paletteItem currentColorPaletteSelection;
	toolItem currentToolSelection;
	AsciiDrawFrame parent;
	boolean drawing = true; //yes, drawing (not erasing)
	asciiCursor theCursor;
	int highlightBorderWidth = 1;  //highlight of a sqaure in the main panel
	int mode = ToolType.PENCIL;

	boolean dirty = true;  //tells when to actually loop through all of the data on
	//a repaint.


	public AsciiDrawPanel(AsciiDrawFrame p, int sqrsize)  {
	rows = sqrsize;
	columns = sqrsize;
	parent = p;
	theCursor = new asciiCursor(this, rows, columns, 5,5);


	positions = new Hashtable();
	keys = new Vector();


	//System.out.print("LOADING.....");
	int x = 0;
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < columns; j++)
		{
			Coordinate key = new Coordinate(i,j);
			keys.addElement(key);
			Switch dirt = new Switch(false, THEchar, THEcolor);  //
			positions.put(key,dirt);
		}
		x++;
		}
		//System.out.println("DONE LOADING");
	}

	public void setStatusLabel(String s) {
		parent.setStatusLabel(s);
	}

	public void setCursor() {
		Graphics g = this.getGraphics();  //the REAL visible graphics!

		//erase old highlight draw new one
		//---> Since this flashes off and on if the old loc = current loc,
		//we dont do this in that case.

		if (  (!(theCursor.getLastLoc().equals(theCursor.getLoc())))  )
		unHighlight(g, theCursor.getLastLoc().getX(), theCursor.getLastLoc().getY());

		//highlight(buffer, theCursor.getLoc().getX(), theCursor.getLoc().getY()); 
		drawHighlightOnSquare(g, theCursor.getLoc().getX(), theCursor.getLoc().getY());

	}


	public void setDrawing() {
		// System.out.println("drawing");
		drawing = true;
	}
	public void setErasing() {
		// System.out.println("erasing");
		drawing = false;
	}
	public boolean isDrawing() {
		return drawing;
	}
	public void setColorAndChar(Color c, String s) {
		THEcolor = new Color(c.getRGB());   
		THEchar = new String(s);
	}
	public void setColorPaletteSelection(paletteItem newPaletteSelection) {
	parent.setColorPaletteSelection(newPaletteSelection);
		}


	public void setTool(int kind) {
		mode = kind;
	}
	public void setToolSelection(toolItem newToolSelection) {
		parent.setToolSelection(newToolSelection);
	}          


	public void setDirty() {
		dirty = true;
	}

	//goes throuugh ALL of the data and paints everything
	//Unless we are still waiting on the users desicion to
	//undo a clear in which case we only draw the panel boarder

	//Note: one annoying case:  user clears then resizes then does "undo clear"
	//for this I need a HACK  (look in code for undo in the event handler and also
	// below in the paint method)
	public boolean SIZEDCHANGED = false;  //means "has sized changed since last undo performed?"
	public void paint(Graphics g) {

		int oneW = this.size().width/columns;
		int oneH = this.size().height/rows;

		im2s = new Dimension(this.size().width, this.size().height);

		//if size has changed, make new image
		if ( !((im2s.width == recentSize.width)&&(im2s.height == recentSize.height)) ) {	
			SIZEDCHANGED = true;	  	
			setDirty();
			im2 = null;  //garbage collector heaven
			//I remember seeing a better way to immediately induce garbage collection... (?)
			im2 = createImage(this.size().width, this.size().height);
			recentSize = null;
			recentSize = new Dimension(im2s.width, im2s.height);
		}

		if (dirty) {       
			im2g = im2.getGraphics(); //new image
			im2g.setColor(Color.white);  //clear it to white
			im2g.fillRect(0, 0, im2s.width, im2s.height);

			//If we aren't waiting for a user's decision about undo clear
			//Or it is that one special HACKy case, then paint the hard way
			if ( (!(parent.nextUndo)) ) {
				int x = 0;
				//set cursor to WATCH -- this next operation is quite lengthy
				for (int i = 0; i < rows; i++)
				{
					//		System.out.print(i + " ");
					for (int j = 0; j < columns; j++)
					{
						Switch sw = (Switch)positions.get(keys.elementAt(x));
						if ( sw == null )
							System.out.print("got null --> ERROR");
						else
							if (sw.isOn() == true) {
								drawSquare(im2g, i, j);  //draw the square with data
							}
						x++;
						}
					}
					dirty = false;  //we drew it, so we are now "clean"
					SIZEDCHANGED = false;  //also we are now at our new size so reset this
					//set cursor to NORMAL POINTER CURSOR
				}


				drawActiveFrame(im2g);  //the frame around the entire image
			}

			//in any case, by now im2 is a "valid" image, so just stick it in g.
			//we use dirty, so im2 the old one will be used here.  :-)
			//System.out.println("drawImage:" + im2);
			g.drawImage(im2,0,0,null);  //finally, draw it into our real panel graphics
	}

	public void repaint() {
		//System.out.println("repaint...");
		paint(this.getGraphics());
		//standard textbook remark:  "overriding this prevents flashes in some cases"
	}

	public String getChar() {
		return THEchar;
	}       

	//call this before doSave(true)
	public void setDestFile(String s) {
		System.out.println("filename is " + s);
		destFile = new File((new String(s)));
	}

	public void doSave(boolean fprint, int kind) {
		//kind == 1  is ascii normal (like this!)
		//kind == 2  also include the Java code that would generate the
		//image they drew

		//NOTE: the CODEGEN parts below are neccessarily confusing because I'M
		//writing out Java code inside of Java code!  Also, I've optimized so the
		//code will be shorter than the obvious way, so the code is even more obscure.
		//Sorry, that's life.

		String result = "\n";	

	//ignore the last few empty rows
	int p = 0;
	boolean outerBreak = false;
	int lastSignificantRow = rows-1;
	for (int i = rows-1; i >= 0; i--)
		{
		for (int j = 0; j < columns; j++)
		{
			p = j*columns + i;
			Switch sw = (Switch)positions.get(keys.elementAt(p));

			if ( sw==null )
				System.out.print("DATA ERROR");
			else
				if (sw.isOn() == true) {
					lastSignificantRow = i;
					outerBreak = true;
					break;
					}
				}
			if (outerBreak)
				break;
		}

	if (outerBreak == false)  //then there is no data, stop here!
		return;


	int entries = 0;

	//The "code" part here is to generate java code
	//that will paint the image one space per pixel
	//to a Java Graphics object 'g'.

	boolean CODEGEN = false;  //don't attach Java code version too

	if (kind == 2)    //if this was called with kind flag == 2
		CODEGEN = true; //then also put the Java code
	//at the bottom.
	//The java code if run in a Java program
	//will paint the image they drew
	//using the same colors as they did
	//with the scale 1 space = 1 pixel.
	//text will be transparent pixels.

	Color lastColor = Color.white;
	String code = "// Generated by AsciiDraw\n" 
				+ "// (c) 1996, Joe Heitzeberg.  joeh@goldbay.com\n" 
				+ "// http://www.goldbay.com/joeh\n"
				+ "// If you want some picture to be used in a Java\n"
				+ "// program, but you don't want to code it up,\n"
				+ "// just draw it with AsciiDraw and output the code!\n"
				+ "// Because it is hard-coded, it is fast\n";

	//draw the image and ignore any empty rows at the start
	boolean goAhead = false; //dont write the first few, if any, empty rows
	String currentRow = "";
	int x = 0;

	boolean inRect = false;
	int jstart = 0;

	for (int i = 0; i <= lastSignificantRow; i++) {
		currentRow = "";  //ready for another row
		for (int j = 0; j < columns; j++) {
		x = j*columns + i;
		Switch sw = (Switch)positions.get(keys.elementAt(x));

		if ( sw==null )
		System.out.print("Uh-oh DATA ERROR.  Better restart...");
		else {
		if (sw.isOn() == true) {
		currentRow = currentRow + sw.getChar();		
		goAhead = true;
		if (CODEGEN) {
			if (!inRect) {
				inRect = true;
				jstart = j;
				if (!(lastColor.equals(sw.getColor()))) {
					lastColor = sw.getColor();
					code = code + "g.setColor(new Color("
					+ sw.getColor().getRGB()  +"));\n";	
				}
		}
	else
		if (!(lastColor.equals(sw.getColor()))) {
		code = code + "g.fillRect("+ jstart + ", "
		+ i +", " + (j - jstart) + ", 1); \n";
		jstart = j;

		lastColor = sw.getColor();
		code = code + "g.setColor(new Color("
		+ sw.getColor().getRGB()  +"));\n";
		}
	}
	}
	else {  //current cell is off 
	currentRow = currentRow +  " ";
	if (CODEGEN) {
	//check if a rect to draw has just finished
	if (inRect) {  //yup we we doing a rect!
	inRect = false;  //then add code to draw it
	code = code + "g.fillRect("+ jstart + ", "
	+ i +", " + (j - jstart) + ", 1); \n";
	//lastColor = Color.white; //our transparent color
	}
	}
	}
	}
	}
	//done with a row;
	if (CODEGEN) {
	if (inRect) {
	code = code + "g.fillRect("+ jstart +", "
	+ i +", " + (columns-jstart) + ", 1); \n";
	inRect = false;
	}
	}
	if (goAhead)
	result = result + currentRow + "\n";

	}
	//done, add one blank row for separation
	result = result + "\n";

	//TEST USE HERE!!!

	if (CODEGEN)
	result += code + "\n //End of AsciiDraw generated code section." ;

	if (fprint)  //file out result
	{	
	//message at the top of the output of files
	result = "[[ Created with AsciiDraw   http://weber.u.washington.edu/~picasso/index.html ]]\n"
	+        "[[   Make sure you use a monospace font such as Courier to view your output   ]]\n\n" + result;  
	try {
	writeStrToFile(result); 
	}
	catch (SecurityException se)
	{
	String seStr = " ";
	seStr = seStr + "SECURITY VIOLATION - file write attemted\n";
	seStr = seStr + "...I guess you are running this from a Browser such as Netscape...\n";
	seStr = seStr + "Browsers won't let you write files.\n";
	seStr = seStr + "To save your results you'll need to run this as an standalone.\n";
	seStr = seStr + "   1. Download the class files.\n";
	seStr = seStr + "   2. Run as a standalone (i.e.  java AsciiDraw).\n";
	seStr = seStr + "   --To do this you need the JDK, but you already know that, right?\n";

	PreviewFrame pf = new PreviewFrame(400,200, seStr);
	pf.show();
	}
	}
	else       //standard out result to preview window
	{
	//System.out.print(result);
	PreviewFrame pf = new PreviewFrame(550,450, result);
	pf.show();
	}
	}


	//regardless of data, put a highligh on the sqaure
	private void drawHighlightOnSquare (Graphics gg, int cooX, int cooY) {
	int oneW = this.size().width/columns;
	int oneH = this.size().height/rows;

	gg.setColor(Color.yellow);
	int xxx = cooX*oneW;
	int yyy = cooY*oneH;

	gg.fillRect(xxx,yyy, oneW, highlightBorderWidth); //top
	gg.fillRect(xxx,yyy+oneH-highlightBorderWidth, oneW, highlightBorderWidth);  //bottom
	gg.fillRect(xxx,yyy,highlightBorderWidth, oneH);   //left
	gg.fillRect(xxx+oneW-highlightBorderWidth, yyy, highlightBorderWidth, oneH);   //right    
	}

	//regardless of data, clear this space
	private void clearSquare (Graphics gg, int cooX, int cooY) {
	int oneW = this.size().width/columns;
	int oneH = this.size().height/rows;

	gg.setColor(Color.white);
	gg.fillRect(cooX*oneW, cooY*oneH, oneW, oneH);
	}


	//Draw the square depending on what data is there.  Clears first.
	private void drawSquare(Graphics gg, int cooX, int cooY) {
	int oneW = this.size().width/columns;
	int oneH = this.size().height/rows;

	//System.out.println("typed " + cooX +","+ cooY);

	//uh-oh protection...if location
	if ((cooX < columns) && (cooY < rows) && (cooY >= 0) && (cooX >= 0))  
	{
	// gg.setColor(Color.white);
	// gg.fillRect(cooX*oneW, cooY*oneH, oneW, oneH);
	clearSquare(gg, cooX, cooY);

	int arrayNum = (cooX*rows + cooY);

	//setDrawing();
	Switch sw = ((Switch)positions.get(keys.elementAt(arrayNum)));

	if ( sw==null )
	System.out.print("got null BAD... drawsquare");
	else
	if (sw.isOn()) {
	//draw the rectangle...and if it is a typed char
	gg.setColor(sw.getColor());
	gg.fillRect(cooX*oneW, cooY*oneH, oneW, oneH);
	if (sw.reallyShowChar())  //then show on the screen too
	{
	gg.setColor(Color.black);
	drawStringWell(gg, sw.getChar(), cooX*oneW, cooY*oneH);
	}
	}
	}
	else System.out.println("JOE - FIX ME drawsquare");

	drawActiveFrame(gg);  //redraw the entire canvas's bounds
	}

	//private void highlight(Graphics gg, int coordX, int coordY) {
	////draw the square with highlight
	//if (parent.nextUndo)  //then we are still waiting for a user's undo action desicion
	//  drawHighlightOnSquare(gg,coordX, coordY);  //so just show highlight the square only
	//else
	//{
	//   drawSquare(gg, coordX, coordY);  //draw from the data
	//   drawHighlightOnSquare(gg, coordX, coordY);
	//}
	//}

	private void unHighlight(Graphics gg, int coordX, int coordY) {
	//draw the square with no highlight
	if (parent.nextUndo)  //then we are still waiting for a user's undo action desicion so just fill white
	clearSquare(gg, coordX, coordY);   
	else
	drawSquare(gg, coordX, coordY);  //draw from the data
	}

	private void drawActiveFrame(Graphics g) {
	//draw around area we are using
	// since the size we have and the size we use can be different
	//deping on the window size and the division (since pixels=int)
	int oneW = this.size().width/columns;
	int oneH = this.size().height/rows;
	g.setColor(Color.darkGray);
	g.drawLine(0,0,oneW*columns,0);
	g.drawLine(0,0,0,oneH*rows);
	g.drawLine(oneW*columns,oneH*rows,oneW*columns,0);
	g.drawLine(oneW*columns,oneH*rows,0,oneH*rows);
	}
	public void clearGraphics() {
	//fast clear visually the data being displayed, but leave
	//the stand-in graphics im2g as is ready to save the day
	//quickly in case the user choses undo clear.
	Graphics g = this.getGraphics();
	Dimension d = this.size();
	g.setColor(Color.white);
	g.fillRect(0, 0, d.width, d.height);

	drawActiveFrame(g);
	}

	//clears the data only. (use clearGraphics to clear the screen only)
	//then if the user misses the chance to undo the clear,
	//zap the data
	public void doClear() {

	//clear the stand-in image that would have been be copied in
	//if they had chosen undo.
	im2g.setColor(Color.white);
	im2g.fillRect(0, 0, im2s.width, im2s.height);

	//loop through clearing the data
	Enumeration ee = positions.keys(); //get everyone directly
	while (ee.hasMoreElements())
	{
	Switch sw = (Switch)positions.get(ee.nextElement());
	if ( sw==null )
	System.out.print("DATA ERROR encountered, I suggest restarting this applet");
	else
	sw.turnOff();
	}
	}

	Dimension dd;
	int arrayNumm;
	Switch sww;
	int ww, hh;
	private boolean check4Fill(Graphics g, int cooX, int cooY, Color oc,  Color nc) {
	arrayNumm = (cooX*rows + cooY);
	//im2s == this.size();
	ww = im2s.width/columns;
	hh = im2s.height/rows;
	sww = ((Switch)positions.get(keys.elementAt(arrayNumm)));

	if (sww.getColor().equals(oc))  {
	sww.setChar(THEchar, false); //these kind don't show on the screen, just in ascii version
	sww.setColor(nc);
	g.setColor(nc);
	g.fillRect(cooX*ww,cooY*hh, ww, hh);
	im2g.setColor(nc);
	im2g.fillRect(cooX*ww,cooY*hh, ww, hh);
	return true;
	}

	return false;
	}

	public void areaFill(Graphics g, Color oc, Color nc, int cooX, int cooY) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -