Escrever em Imagem

3 respostas
Danieldt

gostaria de saber se alguem sabe alguma forma de escrever um texto em uma imagem dentro de um “retangulo” quebrando linhas automaticamente se necessário,
como no html escrever um texto dentro de uma div com largura definida…

tipo, pesquisando achei o Graphic … g.drawString(“texto”,int x,int y);
mas, só isso não resolve meu problema…

tem a imagem ai como exeplo do que eu quero…

aproveitando a oportunidade se alguem souber tambem como escrevo na vertical iria ajudar…

3 Respostas

cristian_clever

Olá amigo para imprimir em qualquer posicao o texto basta vc dar um roatate no Graphics.

Ja o problema do calculo das quebras de linhas, é um pouco mais complexo…
A algum tempo eu desenvolvi um componente de impressão, sendo que uma das funcionalidades dele era exatamente realizar o calculo das quebras dentro de um determinado espaço.

Infelizmente o componente é um pouco grande, antes de te mandar o cara inteiro, vamos apenas colocar o método principal, que o cara que efetivamente realiza a quebra.

Algumas observações:

otherPaneDescription eh um JtextPane nele, é setado o texto completo para ser quebrado via “otherPaneDescription.setText(bufferTexto.toString())”
a seguir ao setarmos o tamanho dele e dar um validate, o componente automaticamente dimensiona as quebras de texto.
Aí a grande sacada…A chave para tudo são as views que sao obtidas do JtextPane. essas views deverão ser quebradas em subviews.
São realizados alguns calculos adicionais para que seja possível obter o tamanho da quantidade de página consumida, poisqdo eu estourar essa quantidade, devo gerar uma nova página.

/**
	 * Realiza a criacao da paginacao e dos componentes utilizados para
	 * realiza-la
	 */
	protected void createPrintable() {

		System.gc();
		System.runFinalization();

		configPrintAtributes();

		page = -1;
		listBufferedImage.clear();
		mapParagrafosPorPagina.clear();

		int x = (int) pf.getImageableX();
		int y = (int) pf.getImageableY();

		Rectangle imagebleArea = new Rectangle((int) pf.getImageableWidth(), (int) pf.getImageableHeight());
		Rectangle totalArea = new Rectangle((int) pf.getWidth(), (int) pf.getHeight());
		

		otherPaneDescription.setSize(imagebleArea.width, imagebleArea.height);
		otherPaneDescription.setPreferredSize(new Dimension(imagebleArea.width, imagebleArea.height));
		otherPaneDescription.validate();
		otherPaneDescription.setVisible(true);

		Dimension dim = otherPaneDescription.getUI().getPreferredSize(otherPaneDescription);
		Rectangle rect0 = new Rectangle(dim.width, dim.height);

		/*
		 * Obtendo as Views
		 */

		View v0 = otherPaneDescription.getUI().getRootView(otherPaneDescription);

		int count = v0.getView(0).getViewCount();

		Graphics g = null;
		BufferedImage bfi = null;

		int maxH = imagebleArea.height;

		int allocY = 0;
		int lastH = 0;

		/*
		 * TODO: O algoritimo que foi construido nao quebra linhas grandes... na
		 * verdade, ele joga uma linha muito grande para um proxima pagina...
		 * Devera no futuro ser desenvolvida uma forma de quebrar uma view
		 * exageradamente grande em duas ou mais views... Cristian Clever
		 */

		for (int i = 0; i < count; i++) {

			View paragrafo = v0.getView(0).getView(i);
			Rectangle alloc = v0.getView(0).getChildAllocation(i, rect0).getBounds();
			allocY += lastH;
			alloc.y = allocY;

			/*
			 * inicia uma nova pagina com altura igual a 'maxH'
			 */
			if ((allocY + alloc.height) >= maxH || i == 0) {

				page++;

				allocY = 0;
				alloc.y = 0;
				lastH = -1 * alloc.height; // negativo para zerar

				// AllocY deve Cair para 0

				// Cria um novo BufferedImage para desenhar o 'preview'
				bfi = getImage();
				g = bfi.getGraphics();
				g.setColor(Color.black);

				// Desenha uma linha
				// g.drawLine(20, 30, (int)pf.getImageableWidth(), 30);
				printPageNumberDetail(g, true);

				// g.setClip(imagebleArea);

				g.setClip(totalArea);
				g.translate(x, y);

				listBufferedImage.add(bfi);
			}

			// DESENHA UM RECTAGLE EM VOLTA de cada linha
			if (false) {
				g.setColor(Color.ORANGE);
				g.drawRect(alloc.x, alloc.y, alloc.width, alloc.height);
			}
			// Desenha o texto na area de visualizacao
			paragrafo.paint(g, alloc);

			List<ComplexView> listParagrafos = mapParagrafosPorPagina.get(Integer.valueOf(page));
			if (listParagrafos == null) {
				listParagrafos = new ArrayList<ComplexView>();
				mapParagrafosPorPagina.put(Integer.valueOf(page), listParagrafos);
			}

			listParagrafos.add(new ComplexView(paragrafo, alloc));

			// Mostar o numero das linha do lado direito da pagina
			// g.drawString("-" + i, alloc.width + 10, alloc.y + (alloc.height /
			// 2));

			lastH = alloc.height;
		}

	}

A idéia principal é o conceito das views, procure estudar um pouco o funcionamento delas!!!

Se não me engano existe um outro conceito, o de fontMetrics (acho que é isso) onde vc escreve um texto e obtem o tamanho de cada palavra… é ujm outro caminho que vc poderá seguir…
Mas, particularmente acredito que a primeira solução(views) será o melhor caminho!

[]s

Danieldt

to achando que vou fazer dentro de um JTextArea, da um wrapLine true, transformar em graphics… ate ai tudo bem… e manda desenhar no meu outro graphics, só que isso ainda nun vi como fazer… tem soh um Graphics.drawImage mais que recebe um Image … o que vc acham?

Danieldt

Dei uma pesquisada ali e não há necessidades de verificar o FontMetrics nen view, pelomenos pro meu caso, tudo que eu precisava esta aqui http://java.sun.com/docs/books/tutorial/2d/text/drawmulstring.html
exatamente o que eu queria…

obrigado

Criado 17 de setembro de 2009
Ultima resposta 24 de set. de 2009
Respostas 3
Participantes 2