Impressão de Canvas

14 respostas
M

Olá pessoal. Estou com um problema na geração de imagem a partir de um Canvas. Quando eu vejo o Canvas na tela, ele aparece com texto em baixa resolução (pixalizado e quase não dá para ler). Estou gerando uma imagem a partir do Canvas e vem igualzinho ao que vejo na tela. Tudo bem até aqui. O problema é que, quando eu envio o Canvas para a impressora, eu consigo uma impressão com os textos claros e bem definidos. Mas ao gerar a imagem, obviamente isso não acontece. Alguém sabe como resolver meu problema? Eu já tentei gerar a imagem maior, mas depois ela excede o tamanho da folha tanto no Canvas quanto a imagem por si só.

Alguém já teve esse problema? Alguém sabe melhorar a qualidade dos textos na imagem gerada (bitmap, png e jpeg, todos saem da mesma forma)?

14 Respostas

ViniGodoy

Sua aplicação é desktop ou mobile?

Se for desktop, por que está usando o Canvas, que é da AWT, e não o JComponent, que é do Swing?

ViniGodoy

Você pode postar o código que está usando para gerar a imagem?

M
public void paint(Graphics graph)
    {
        //no caso, por enquanto, Canvas e Image
        ArrayList<EstruturaDesenho> contextosDesenho = new ArrayList<EstruturaDesenho>();
        contextosDesenho.add(new EstruturaDesenho(graph, getModelo().getUnidadeMedida()));
        contextosDesenho.add(new EstruturaDesenho(getEtiquetaImagem().getGraphics(), "img" + getModelo().getUnidadeMedida()));
        //desenhando os componentes nos contextos
        for (ComponenteModelo componente : getModelo().getComponentes())
        {
            for (EstruturaDesenho estrutura : contextosDesenho)
            {
                Graphics grafico = estrutura.getGraphics();
                grafico.setColor(Color.BLACK);
                componente.desenharComponente(grafico, estrutura.getUnidadeMedida());
            }
        }
		
        //limpando o arraylist para não ficar lixo na memória
        //apesar do Garbage Collector, é melhor não arriscar
        contextosDesenho.clear();
        contextosDesenho = null;
    }

Simplificando: estou criando uma imagem BufferedImage e chamando o paint do Canvas nela. Eu testei com o JComponent agora e obtive o mesmo resultado. Não utilizei ele por estar familizarizado com o nome Canvas para esse tipo de finalidade. Não sabia que existia o seu equivalente no swing. A aplicação é desktop.

EDIT: Apenas para mencionar. O problema foi “solucionado”. Na hora de desenhar textos na tela, eu aumentei a fonte definida em 3. Tive que obviamente mover todo o resto. Gostaria que a imagem fosse gerada como era quando eu enviava o Canvas para impressora. E não ficar em cima de uma gambiarra.

ViniGodoy

Já tentou ligar o AntiAlias e definir alguns RenderingHints? Logo no início do seu método, você pode tentar fazer:

Graphics2D g = (Graphics2D) graph; g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

Prefira os componentes Swing em relação aos da AWT. Além dos da AWT serem heavyweight (e ficarem sobre os do Swing), o do Swing ainda é acelerado por hardware e tem por padrão double buffering.

M

Muito obrigado, ViniGodoy! Como nunca mexi bem com a biblioteca gráfica do Java, desconheço todos os seus componentes e os métodos destes. Da próxima vez, vou buscar mais nas definições das classes que utilizo antes de postar alguma dúvida.

Agora, infelizmente, não chegou no resultado desejado ainda. O texto até ficou melhor, mas o AntiAlias ficou muito ruim no texto e no resto da imagem é desnecessário. Em algumas partes (onde o texto era BOLD) acabou borrando a letra. O resultado que havia obtido na impressora era infinitamente melhor 0.o.

Vou colocar a imagem gerada (antes da gambiarra) e o que imprimia na impressora (com uma impressora PDF) para comparação.

EDIT:
Segue um link para download do .pdf e de um .png com as etiquetas antes de arrumar (com a gambiarra) e também antes de aplicar o Anti Alias no rendering do graphics
http://www.megaupload.com/?d=WN5Z7Z0I

samuel.grigolato

Não definiria como gambiarra. Fazer um Cast para Graphics2D foi a maneira que a Sun encontrou de manter o backward compatibility com componentes antigos sem deixar de expor novas funcionalidades, pode usar a instância de Graphics2D sempre que ver uma referência a Graphics que é aceitável.

ViniGodoy

Geralmente borrões ocorrem quando você converte a imagem para algum formato com compactação, como o jpg.

Você está gravando a imagem no disco?

M

O borrão fica no Canvas mesmo. Eu estou usando .png e .bmp. Sim, estou gravando no disco.

A gambiarra não é a dele não ^^. Eu sei o que você comentou sobre o Graphics2D e o Graphics. É muito mais que aceitável. Peço desculpas por ter sido escrito de forma confusa e ter possibilitado uma outra interpretação.

A gambiarra a qual me referi é a minha. Na hora de desenhar os textos, eu aumento o tamanho da fonte em 3, sem motivo aparente. Essa é a gambiarra.

Coloquei o link no post acima porque não vi as respostas, segue o link para comparação dos resultados (imagem gerada via Java e .pdf com impressão via impressora PDF, era como saia na impressora normal)
http://www.megaupload.com/?d=WN5Z7Z0I

ViniGodoy

Bom, é difícil dizer por que o problema ocorre. Exigiria uma análise mais detalhada no código.
Mas não é normal, deve ser algum detalhe macabro.

M

Bom, muito obrigado de qualquer forma! O anti alias melhorou mais ainda a impressão ^^. Fico agradecido pela ajuda.

ViniGodoy

Dá uma lida nos artigos de Java 2D do meu site. Vão te esclarecer várias coisas importantes.
Por exemplo, é necessário fazer uma cópia do contexto gráfico antes de iniciar a pintura. E notei que você não está fazendo.

Talvez isso esteja deixando sujeira.

M

Vou arrumar isso assim que possível. Estou sem acesso ao código-fonte no momento. Assim que mudar, posto sobre o resultado.

Eu dei uma lida bem por cima dos artigos do seus site. Achei bem interessante ^^, sempre havia me perguntado como o pessoal usava o Java2D para jogos (apesar de ter uma noção).

M

Não tive a melhora obtida. Ainda não sei qual a diferença e nem onde a página de impressão é desenhada. Mas meu resultado foi melhorado e já consertado de outras formas.

Agradeço a atenção de todos.

ViniGodoy

Beleza. Se conseguir descobrir, volte aqui no tópico e poste sobre a descoberta. Eu fiquei curioso do porque da diferença. heheheh

Criado 30 de julho de 2010
Ultima resposta 2 de ago. de 2010
Respostas 14
Participantes 3