Gå til innhold

[Løst]Lage et 'viskelær' i java


Anbefalte innlegg

Lager en kodesnutt som skal levere et bilde der mye er transparent. Jeg tegner på det med delvis transparente ikoner, og for å unngå å se de underliggende ikonene ved overlap ønsker jeg å benytte et alphaimage, som er det samme ikonet bare helt opaque, til å slette de deler av det underliggende ikonet.

 

Hvordan kan jeg gjøre det?

Endret av Fluesoppen
Lenke til kommentar
Videoannonse
Annonse

Jeg har et bufferedimage, som jeg ønsker skal være gjennomsiktig. På dette tegner jeg flere trær, som tildels er gjennomsiktige. På grunn av at de er gjennomsiktige vil stammen på det treet over vise gjennom på det andre treet. Jeg vil slette denne stammen før jeg tegner det neste treet. Går det ann?

 

Kan poste koden, så kanskje det er litt lettere å forstå:

 

package mapmaking;

import java.awt.Graphics;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.Raster;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Main {

BufferedImage[] tree = new BufferedImage[12];
BufferedImage[] alpha = new BufferedImage[12];
BufferedImage mask;
BufferedImage workImg;
//	double scale = 1; // find out how to change grid size according to scale
int treeSize = 20;
int gridSize = 5;
int gridsPerTree = treeSize / gridSize; // Should be 2? Means two grids in each direction; four alltogether.
//	double ySpacing = 1;
//	double xSpacing = 1;
//	double yGrid = 1;
//	double xGrid = 1;
//	double random = 0;
//	boolean trees = false;
int width;
int height;
JFrame frame;
ImageViewer viewer;
int id = 1;
private int gridX;
private int gridY;
int imageMatrix[][];
private boolean maskLoaded = false;
JMenuBar jmbMenu = new JMenuBar();
JMenuItem jmSave = new JMenuItem("Save");
JMenuItem jmLoad = new JMenuItem("Load");
JFileChooser jfc = new JFileChooser();
JCheckBox jcbFill = new JCheckBox("Fill");

public Main() {


	frame = new JFrame();
	viewer = new ImageViewer(workImg, this);

	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.setContentPane(viewer);
	frame.setBounds(300, 50, 650, 650);
	frame.setVisible(true);

	frame.setJMenuBar(jmbMenu);
	jmbMenu.add(jmLoad);
	jmbMenu.add(jmSave);
	jmbMenu.add(jcbFill);

	jmLoad.addActionListener(new ActionListener() {

		public void actionPerformed(ActionEvent e) {
			loadImage();
		}
	});
	jmSave.addActionListener(new ActionListener() {

		public void actionPerformed(ActionEvent e) {
			saveImage();
		}
	});
	jcbFill.addActionListener(new ActionListener() {

		public void actionPerformed(ActionEvent e) {

			drawTrees();
		}
	});

	for (int i = 0; i < tree.length; i++) {
		tree[i] = readImage("Images/Tree" + i + ".png");
		alpha[i] = readImage("Images/Alpha" + i + ".png");
	}
}

public void createImage() {
	width = mask.getWidth();
	height = mask.getHeight();


	BufferedImageOp op = new AffineTransformOp(
			AffineTransform.getScaleInstance(0.2, 0.2), //Why 0.2? Can't remember. Probably not right.
			new RenderingHints(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC));
	mask = op.filter(mask, null);
	System.out.println(mask.getWidth());
	Raster raster = mask.getAlphaRaster();

	imageMatrix = getCleanMatrix();
	for (int x = 0; x < gridX; x++) {
		for (int y = 0; y < gridY; y++) {
//				System.out.print(raster.getSample(x, y, 0) + " ");
			if (raster.getSample(x, y, 0) == 0) {
				imageMatrix[x][y] = 255;
			} else {
				imageMatrix[x][y] = 0;
			}
		}
		System.out.println();
	}
	maskLoaded = true;
	drawTrees();
}

public int[][] getCleanMatrix() {
	gridX = (width / gridSize);
	gridY = (height / gridSize);
	System.out.println("gridX: " + gridX);
	System.out.println("gridY: " + gridY);

	return new int[gridX][gridY];
}

public void drawTrees() {
	int[][] matrix = getCleanMatrix();
	if (maskLoaded) {
		for (int x = 0; x < gridX; x++) {
			for (int y = 0; y < gridY; y++) {
				matrix[x][y] = imageMatrix[x][y];
			}
		}
	} else {
		width = 1024;
		height = 1024;
		matrix = getCleanMatrix();
	}
	workImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
	viewer.setImage(workImg);
	drawTrees(matrix);
}

public void drawTrees(int[][] matrix) {
	Graphics g = workImg.getGraphics();
	int jumpStep = 10;
	for (int i = 0; i < 6; i++) {
		generateTrees(g, matrix, jumpStep * gridsPerTree);
	}
	generateTrees(g, matrix, gridsPerTree);
	viewer.setImage(workImg);
	System.out.print("Stopped");
//		saveImage("Output.png");
}

public void generateTrees(Graphics g, int[][] matrix, int jump) {
	Random r = new Random();
	for (int y = 0; y < gridY - gridsPerTree; y++) {
		for (int x = r.nextInt(3 * gridsPerTree); x < gridX - gridsPerTree; x += r.nextInt(jump)) {
			if (checkMatrix(matrix, x, y)) {
//					System.out.println("Drawing a tree at " + x + " " + y);
				fillMatrix(matrix, x, y, id++);
				int nextTree = r.nextInt(tree.length);
				if (jcbFill.isSelected()) {
					g.drawImage(alpha[nextTree], x * gridSize, y * gridSize, null);
				}
				g.drawImage(tree[nextTree], x * gridSize, y * gridSize, null);
				viewer.setImage(workImg);
			}
		}
	}
}

public boolean checkMatrix(int m[][], int x, int y) {
	for (int i = x; i < x + gridsPerTree; i++) {
		for (int j = y; j < y + gridsPerTree; j++) {
			if (m[i][j] != 0) {
				return false;
			}
		}
	}

	return true;
}

public void fillMatrix(int m[][], int x, int y, int fill) {
	for (int i = x + 1; i < x + gridsPerTree; i++) {
		for (int j = y; j < y + gridsPerTree - 1; j++) { //-1 because overlap is allowed on the trunk. Might be more overlap perhaps.
			m[i][j] = fill;
		}
	}
}

public void printMatrix(int m[][]) {
	for (int m1[] : m) {
		for (int m2 : m1) {
			System.out.print(m2 + " ");
		}
		System.out.println("");
	}
}

void updateImage(int sm, double yS, double xS, double yG, double xG, double r, boolean tr) {
	drawTrees();
}

public BufferedImage readImage(String path) {
	try {
		BufferedImage img = ImageIO.read(new File(path));
		return img;
	} catch (IOException ex) {
		System.err.println("Error 1. Cannot load image");
		Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
		System.exit(0);
		return null;
	}
}

public void loadImage() {
	int returnVal = jfc.showOpenDialog(frame);
	if (returnVal == JFileChooser.APPROVE_OPTION) {
		try {
			File f = jfc.getSelectedFile();
			mask = ImageIO.read(f);
			createImage();
		} catch (IOException ex) {
			Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
		}
	}

}

public void saveImage() {
	int returnVal = jfc.showSaveDialog(frame);
	if (returnVal == JFileChooser.APPROVE_OPTION) {
		File f = jfc.getSelectedFile();
		saveImage(f);
	}
}

public void saveImage(File f) {
	try {
		ImageIO.write(workImg, "PNG", f);
	} catch (IOException ex) {
		Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
	}
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
	new Main();
}
}

 

 

Altså, problemet ligger i generateTrees(). Jeg har for øyeblikket to varianter av det treet jeg skal tegne; treet, og en mask som skal fungere som 'viskelær'.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...