[RESOLVIDO] Selecionar área de uma imagem

19 respostas
L

Salve galerinha abençoada do GUJ!!

Bem… Estou desenvolvendo uma aplicação a para android q utilizará o Tesseract(api utilizada apara capturar texto presente em uma imagem)…

A proposta da aplicaçao será mais ou menos esta:

[youtube]http://www.youtube.com/watch?v=FOSgiPjGwx4[/youtube]

Mas na aplicação não será “tão simples assim”…
Ela salvará o texto em um BD… mas isso não vem ao caso…

O que eu quero saber é como se fazer para criar esta “area de seleção” mostrada ai no video…

Fiquem com DEUS!

19 Respostas

M

Numa class extends View que faz tudo isso baseado no onTouchEvent

L

Cara, desculpa a minha “ignorancia” relacionado a isso…
Mas, vossa senhoria poderia me indicar algum tutorial ou algum codigo exemplo??

Grato pela atenção!

Fica com DEUS!

M

Não tenho exemplos.

Mas é um pouco de matematica reconhendo as gestures pelo onTouchEvent.

L

Ok…

Galerinha se alguem tiver algo(exemplo ou algo assim) que possa me ajudar agradeço… Pois isso com certeza não vai ajudar só a mim!

Fiquem com DEUS!

L

Bem...

Já avancei um pouco no código...

E estou com este código que está imprimindo uma imagem em um Image View e Riscando uma linha(bem basicão mesmo)..
Intent i = getIntent();
		
		byte[] b = i.getExtras().getByteArray("byteImagem"); //recebe o byte array por parametro do Itent
		        
		InputStream is = new ByteArrayInputStream(b); //InputStream com o b
		
		bit = BitmapFactory.decodeStream(is); //Decodifica o Byte[] para um Bitmap
		bitMutavel = bit.copy(Config.ARGB_8888, true); //Copia o Bitmap acima
		
		p = new Paint(); //Inicia o Paint
		p.setColor(Color.GREEN); //Seta a cor do Paint
		
		c = new Canvas(bitMutavel); //Inicia o canvas
		c.setViewport(IVSelecionar.getWidth(), IVSelecionar.getHeight()); //Seta o tamanho do Canvas
		
		c.drawLine(0, 0, 200, 200, p); //Desenha a linha no canvas
		
		IVSelecionar.setImageBitmap(bitMutavel); //Imrpime o Canvas num Image View

Bem... Quando este código é executado num voi ele funciona beleza... mas como fazer para q apareça a linha quando for clickado no ImageView??

Estou tentando fazer assim:

IVSelecionar.setOnTouchListener(new View.OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// TODO Auto-generated method stub
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					Log.e("DOWN", event.getX()+" x "+event.getY());
					float x = event.getRawX(), y = event.getRawY();
					
					bitMutavel = bit.copy(Config.ARGB_8888, true);
					c = new Canvas(bitMutavel);
					c.setViewport(IVSelecionar.getWidth(), IVSelecionar.getHeight());
					
					c.drawLine(x, y, x+50, y+50, p);
					
					IVSelecionar.setImageBitmap(bitMutavel);
					break;
				case MotionEvent.ACTION_UP:
					//Log.e("UP", event.getX()+" x "+event.getY());
					break;
				case MotionEvent.ACTION_MOVE:
					Log.e("UP", event.getX()+" x "+event.getY());
					break;
				}
				return true;
			}
		});

Mas ele só desenha a linha de vez em nunca e quando desenha desenha no lugar errado...

Alguem tem uma luz??

L
Galerinha dei um "jeitinho":
IVSelecionar.setOnTouchListener(new View.OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// TODO Auto-generated method stub
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					Log.e("DOWN", event.getX()+" x "+event.getY());
					float x = event.getRawX(), y = event.getRawY();
					
					c.drawLine(x*w, y*h, x*w, y*h+50, p); //w e h são variaveis com a proporção da tela da resulucao do celular para o tamnho do canvas
					
					IVSelecionar.setImageBitmap(bitMutavel);
					break;
				case MotionEvent.ACTION_UP:
					//Log.e("UP", event.getX()+" x "+event.getY());
					break;
				case MotionEvent.ACTION_MOVE:
					//Log.e("MOVE", event.getX()+" x "+event.getY());
					break;
				}
				return true;
			}
		});
L

Bem Galerinha....

O código está marromeno do jeito q eu quero:
IVSelecionar.setOnTouchListener(new View.OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// TODO Auto-generated method stub
				float x = event.getRawX()*w, y = event.getRawY()*h;
				
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					c.drawLine(x, y, x, y+50, p);
					
					pontoNome = new Point((int) x, (int) y);
					
					
					IVSelecionar.setImageBitmap(bitMutavel);
					break;
				case MotionEvent.ACTION_UP:
					break;
				case MotionEvent.ACTION_MOVE:
					bitMutavel = bit.copy(Config.ARGB_8888, true);
					c = new Canvas(bitMutavel);
					
					c.drawLine(pontoNome.x, pontoNome.y, pontoNome.x, y, p);
					c.drawLine(pontoNome.x, pontoNome.y, x, pontoNome.y, p);
					c.drawLine(pontoNome.x, y, x, y, p);
					c.drawLine(x, pontoNome.y, x, y, p);
					
					IVSelecionar.setImageBitmap(bitMutavel);
					break;
				}
				return true;
			}
		});

Porém quando apessoa toca e arrasta o dedo fica travando....

Eu acredito que isso seja pois ele está "reiniciando" o canvas a cada movimento que a pessoa faz com o dedo...(obs: Estou rodando num Galaxy Y)....

Tem algum jeito de remover ou ao menos diminuir este "delay"??

Fiquem com DEUS e obrigado pela atenção!

M

É mais facil voce criar uma View (extends) sua que desenhe essas coisas no Canvas no onDraw invés de trocar o Bitmap.

Mude os parametros dentro da classe e de invalidate() para redesenhar.

L

Marky obrigado pela atenção!

No caso o codigo utilizado seria mais ou menos como este:


??

M

Sim, isso mesmo. Só não é realmente necessario um SurfaceView se voce nao precisar fazer updates de outra thread.

L

Cara desculpa a demora a responder, desculpa pelo trabalho que estou dando e obrigado pela atençao…

Mas seria possivel aplicar este metodo do onDraw a uma ImageView??

Fica com DEUS!

M

Pode ser no onDraw da ImageView ou pode ser numa View mesmo, dai voce deixa uma ImageView por baixo.

L

Olá novamente Marky!

Cara enquanto fazia aquela velha varrida de Programador pelo titio Google...

Achei Este Tutorial...

Pelo que vi no site criei esta classe:
public class VizualizadorImagem extends ImageView {

	public VizualizadorImagem(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }
	
	@Override
    protected void onDraw(Canvas canvas)
    {
        // TODO Auto-generated method stub
		super.onDraw(canvas);
		
        Paint paint = new Paint();
        paint.setColor(Color.GREEN); //Seta a cor do Paint
		paint.setStrokeWidth(10);
        paint.setTextSize(12.0F);
        canvas.drawText("Hello World in custom view", 100, 100, paint);
        canvas.drawLine(0, 0, 60, 60, paint);
        
        setImageBitmap(null);
        setBackgroundColor(Color.YELLOW);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        // TODO Auto-generated method stub
        if(event.getAction() == MotionEvent.ACTION_DOWN){
        	Log.e("Hello Android", "Pressionou");
        }
        return super.onTouchEvent(event);

    }

}

Que está sendo chamada assim no XML:

<com.compras.VizualizadorImagem
            android:id="@+IVs/IVSelecionarAreas"
            android:layout_width="match_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:src="@drawable/add" />

Porem o evento onDraw não está "surtindo efeito"no meu image view....

Se eu colocar para ele gerar um Log... ele gera normalmente...

Vossa senhoria conseguiria perceber o que está errado que ele nao está alterando a tela do ImageView??

Grato pea atenção:!:

Fica com DEUS:!:

Obs.: Ele não surte o efeito que eu passo no onDraw.... mas imprime belezinha a imagem passada pelo XML ;)

L
public class VizualizadorImagem extends ImageView {
	Bitmap imagem;

	public VizualizadorImagem(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        
        setImageBitmap(null);
        
        imagem = null;
        // TODO Auto-generated constructor stub
    }
	
	@Override
    protected void onDraw(Canvas canvas)
    {
        // TODO Auto-generated method stub
		Paint paint = new Paint();
        paint.setColor(Color.GREEN); //Seta a cor do Paint
		paint.setStrokeWidth(3);
        
        if(imagem != null){
        	canvas.drawBitmap(imagem, 0, 0, paint);
        }
        
        canvas.drawLine(0, 0, 50, 50, paint);
        
        super.onDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        // TODO Auto-generated method stub
        if(event.getAction() == MotionEvent.ACTION_DOWN){
        	Log.e("Hello Android", "Pressionou");
        }
        return super.onTouchEvent(event);

    }
    
    public void setarImagem(Bitmap bit){
    	imagem = bit;
    }

}

Cara dei um jeito... a classe ficou desta forma aii em cima....

Mas quando ele imprime a imagem ele imprime a imagem cortada :/

Provavelmente porque a resolução capturada pela camera é maior que a da tela do celular.. alguma solução??

Novamente grato pela atenção!

L

Bem galerinha... solucionei a parte de redimensionar a imagem:

Criei este método:

public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
    	int width = bm.getWidth();
    	int height = bm.getHeight();
    	
    	float scaleWidth = ((float) newWidth) / width;
    	float scaleHeight = ((float) newHeight) / height;
    	
    	// CREATE A MATRIX FOR THE MANIPULATION
    	Matrix matrix = new Matrix();
    	
    	// RESIZE THE BIT MAP
    	matrix.postScale(scaleWidth, scaleHeight);
    	
    	// RECREATE THE NEW BITMAP
    	Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
    	return resizedBitmap;
    }

Nele você passa como parametro um Bitmap uma altura e uma largura e ele retorna a imagem redimensionada...

Daqui para terça feira posto como ficou o codigo selecionando a area da imagem....

Fiquem com DEUS! E obrigado pela atenção!

L

Pronto galerinha!

Marky muito obrigado pela sua ajuda!

Meus codigos ficaram assim:

Classe(com.compras.VizualizadorImagem):
package com.compras;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

public class VizualizadorImagem extends ImageView {
	Bitmap imagem;
	Point pontoInicialNome, pontoFinalNome;	

	public VizualizadorImagem(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        
        setImageBitmap(null);
        
        pontoInicialNome = new Point(0, 0);
        pontoFinalNome = new Point(0, 0);
        
        imagem = null;
        
        setarListener();
    }
	
	@SuppressLint("DrawAllocation")
	@Override
    protected void onDraw(Canvas canvas)
    {
		// TODO Auto-generated method stub
		Paint paint = new Paint();
        paint.setColor(Color.GREEN); //Seta a cor do Paint
		paint.setStrokeWidth(2); //Seta a "grossura" do Paint
        
        if(imagem != null){
        	canvas.drawBitmap(imagem, 0, 0, paint);
        }
        
        canvas.drawLine(pontoInicialNome.x, pontoInicialNome.y, pontoFinalNome.x, pontoInicialNome.y, paint);
        canvas.drawLine(pontoInicialNome.x, pontoInicialNome.y, pontoInicialNome.x, pontoFinalNome.y, paint);
        canvas.drawLine(pontoInicialNome.x, pontoFinalNome.y, pontoFinalNome.x, pontoFinalNome.y, paint);
        canvas.drawLine(pontoFinalNome.x, pontoInicialNome.y, pontoFinalNome.x, pontoFinalNome.y, paint);
        super.onDraw(canvas);
    }
	
	public void setarListener(){
		setOnTouchListener(new View.OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if(event.getAction() == MotionEvent.ACTION_DOWN){
		        	pontoInicialNome.set((int) event.getX(), (int) event.getY());
		        }
		        
		        if(event.getAction() == MotionEvent.ACTION_MOVE){
		        	pontoFinalNome.set((int) event.getX(), (int) event.getY());
		        	
		        	invalidate();
		        }
		        
		        if(event.getAction() == MotionEvent.ACTION_UP){
		        	//Aqui ficam os codigos que seram execultados quando a pessoa "tirar" o dedo da tela
		        }
				return true;
			}
		});
	}
    
    public void setarImagem(Bitmap bit, int alt, int larg){
    	imagem = getResizedBitmap(bit, alt, larg);
    }
    
    public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
    	int width = bm.getWidth();
    	int height = bm.getHeight();
    	
    	float scaleWidth = ((float) newWidth) / width;
    	float scaleHeight = ((float) newHeight) / height;
    	
    	// CREATE A MATRIX FOR THE MANIPULATION
    	Matrix matrix = new Matrix();
    	
    	// RESIZE THE BIT MAP
    	matrix.postScale(scaleWidth, scaleHeight);
    	
    	// RECREATE THE NEW BITMAP
    	Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
    	return resizedBitmap;
    }


}
XML:
<?xml version="1.0" encoding="UTF-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
        
        <com.compras.VizualizadorImagem
            android:id="@+IVs/IVSelecionarAreas"
            android:layout_width="match_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1" />

    </LinearLayout>

Fiquem com DEUS e novamente muito obrigado pela atenção de todos!

M

Era isso que eu imaginava mesmo.

Só uma dica: não crie o Paint dentro do método onDraw, crie no construtor e guarde a referencia.

L

Bem galera…

Seguindo a dica do nosso amigo Marky apenas implementei a classe VizualizadorImagem.java com este codigo:

public void iniciarPaint(){ paint = new Paint(); paint.setColor(Color.GREEN); //Seta a cor do Paint paint.setStrokeWidth(2); //Seta a "grossura" do Paint }

E fora dos “voids” declarei o Paint:

A

landantas, teria como me enviar um exemplo de chamada para está class?

Att, André

Criado 18 de julho de 2012
Ultima resposta 29 de jul. de 2013
Respostas 19
Participantes 3