[RESOLVIDO] Selecionar área de uma imagem

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!

Numa class extends View que faz tudo isso baseado no onTouchEvent

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!

Não tenho exemplos.

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

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!

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)…

[code]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[/code]

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:

[code]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;
		}
	});[/code]

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

Alguem tem uma luz??

Galerinha dei um “jeitinho”:

[code]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;
		}
	});[/code]

Bem Galerinha…

O código está marromeno do jeito q eu quero:

[code]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;
		}
	});[/code]

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!

É 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.

Marky obrigado pela atenção!

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


??

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

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!

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

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:

[code]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);

}

}[/code]

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 :wink:

[code]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;
}

}
[/code]

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

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

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

Novamente grato pela atenção!

Bem galerinha… solucionei a parte de redimensionar a imagem:

Criei este método:

[code]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;
}[/code]

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!

Pronto galerinha!

Marky muito obrigado pela sua ajuda!

Meus codigos ficaram assim:

Classe(com.compras.VizualizadorImagem):

[code]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;
}

}
[/code]

XML:

[code]<?xml version="1.0" encoding="UTF-8"?>

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

</LinearLayout>

[/code]

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

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.

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:

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

Att, André