JavascriptProva

Visualizzazione post con etichetta ImageVIew. Mostra tutti i post
Visualizzazione post con etichetta ImageVIew. Mostra tutti i post

domenica 1 maggio 2016

Codice perfezionato per il trascinamento di una bitmap attraverso una ImageVIew.

Ecco il codice perfezionato, per il trascinamento di unìimmagine attraverso una ImageView più piccola.
public class MainActivity extends Activity {

 
 RelativeLayout mainLayout;
 ImageView imageView;
 
 Bitmap bitmap;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  mainLayout=(RelativeLayout)findViewById(R.id.mainLayout);
  
  bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.anguria);
  
 
  ImageView imageView=new ImageView(this);
 
  

  
  imageView.setImageBitmap(bitmap);
  imageView.setBackgroundColor(Color.BLACK);
  imageView.setScaleType(ScaleType.MATRIX);
  
  
  mainLayout.addView(imageView);
  imageView.setX(200);
  imageView.setY(10);
  imageView.getLayoutParams().width=200;
  imageView.getLayoutParams().height=200;
  
  
  View.OnTouchListener onTouchListener=new View.OnTouchListener() {
   Matrix matrix=new Matrix();
   Matrix inversa=new Matrix();
   float X,Y,currentX, currentY;
   float deltaX, deltaY;
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    switch(event.getAction()){
    case MotionEvent.ACTION_DOWN:
     X=event.getX();
     Y=event.getY();
     break;
    case MotionEvent.ACTION_MOVE:
     currentX=event.getX();
     currentY=event.getY();
     float[] pts={0,0};
     ((ImageView)v).getImageMatrix().invert(inversa);
     inversa.mapPoints(pts);
     
     /*se la direzione è da destra a sinistra il punto d'arresto
      * è a bitmap.getWidth-200. Per valori inferiori la 
      * translazione è normale, per valori uguali la translazione
      * è zero, per valori superiori torna al valore massimo
      */
     Log.d(pts[0]+"",""+(bitmap.getWidth()-200));
     if(currentX<X){
      if(pts[0]<(bitmap.getWidth()-200)){
       deltaX=-pts[0]+currentX-X;
      }
      else{
       if(pts[0]>(bitmap.getWidth()-200))
       deltaX=-(bitmap.getWidth()-200);
       
      }
     }
     if(currentX>X){
      if(pts[0]>0){
       deltaX=-pts[0]+currentX-X;
      }
      else{
       if(pts[0]<0) deltaX=0;
      }
     }
     
     if(currentY<Y){
      if(pts[1]<(bitmap.getHeight()-200)){
       deltaY=-pts[1]+currentY-Y;
      }
      else{
       if(pts[1]>(bitmap.getHeight()-200))
        deltaY=-(bitmap.getHeight()-200);
       
      }
     }
     if(currentY>Y){
      if(pts[1]>0){
       deltaY=-pts[1]+currentY-Y;
      }
      else{
       if(pts[1]<0) deltaY=0;
      }
     }
     
     
     matrix.setTranslate(deltaX,deltaY);
     ((ImageView)v).setImageMatrix(matrix);
     X=currentX;
     Y=currentY;
    }
    return true;
   }
  };
  imageView.setOnTouchListener(onTouchListener);
  
  
 }

} 
Sembra perfetto.

mercoledì 20 aprile 2016

Studio per ritagliare immagini (codice grezzo)

Ho realizzato in questo modo una "finestra" sulla bitmap, ossia una ImageView che si "affaccia" su una Bitmap più grande di essa e tramite la quale si può "uncinare" la bitmap spostandola a piacimento.
  imageView =new ImageView(this);
  bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.facciadaculo);
  int larghezza=bitmap.getWidth();
  int altezza=bitmap.getHeight();  

  
  LayoutParams params=new LayoutParams(200,100);
  imageView.setLayoutParams(params);
  imageView.setScaleType(ScaleType.CENTER);
  imageView.setImageBitmap(bitmap);
  imageView.setBackgroundColor(Color.BLACK);
  
  mainLayout.addView(imageView);
  
  OnTouchListener onTouchListener=new View.OnTouchListener() {
   
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    
    switch(event.getAction()){
     case MotionEvent.ACTION_DOWN:
      X=event.getX();
      Y=event.getY();
      break;
     case MotionEvent.ACTION_MOVE:
      currentX=event.getX();
      currentY=event.getY();
      
      int scrollByX=(int)(X-currentX);
      int scrollByY=(int)(Y-currentY);
      v.scrollBy(scrollByX, scrollByY);
      X=currentX;
      Y=currentY;
      break;
    }
    return true;
   }
  };
  imageView.setOnTouchListener(onTouchListener);
 }
Bene.
Annotata questa, procedo a sperimentare un po' oltre...

Provo a usare il metodo scrollTo(int,int).
  OnTouchListener onTouchListener=new View.OnTouchListener() {
   
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    
    switch(event.getAction()){
     case MotionEvent.ACTION_DOWN:
      imageView.scrollTo(0, 0);
      break;
     
      
    }
    return true;
   }
  };
  imageView.setOnTouchListener(onTouchListener);
Giocando con ScaleType e con ScrollTo posso modificare sia la posizione iniziale della bitmap nei confronti della ImageView sia l'entità dello scorrimento della bitmap.
Adesso quello che mi interessa è prendere le coordinate della bitmap.
Se uso ScaleType.MATRIX, ottengo il posizionamento iniziale nell'angolo superiore sinistro della Bitmap, quindi zero.
Ora sposto di 50 e 50:
    switch(event.getAction()){
     case MotionEvent.ACTION_DOWN:
      imageView.scrollTo(50,50);
      break;
     
      
    }


Sposto mediante il Touch di 50,50:



E adesso quindi so di avere una finestra che esplora la bitmap secondo queste coordinate:
Angolo superiore sinistro: 50,50;
Angolo inferiore destro: 150,150 (dato che le dimensioni della finestra sono rispettivamente 100 e 100).

Provo quindi a ritagliare un'immagine di queste coordinate e dimensioni.
Per vederla, però, devo creare una nuova ImageView.

Ecco il codice:
  imageView =new ImageView(this);
  bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.facciadaculo);
  int larghezza=bitmap.getWidth();
  int altezza=bitmap.getHeight();
  
  
  LayoutParams params=new LayoutParams(100,100);
  imageView.setLayoutParams(params);
  imageView.setScaleType(ScaleType.MATRIX);
  imageView.setImageBitmap(bitmap);
  imageView.setBackgroundColor(Color.BLACK);
  
  mainLayout.addView(imageView);
  
  imgControllo=new ImageView(this);
  LayoutParams p=new LayoutParams(100,100);
  p.leftMargin=10;
  p.topMargin=200;
  imgControllo.setLayoutParams(p);
  mainLayout.addView(imgControllo);
  
  OnTouchListener onTouchListener=new View.OnTouchListener() {
   
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    
    switch(event.getAction()){
     case MotionEvent.ACTION_DOWN:
      imageView.scrollTo(50,50);
      Bitmap newBmp=Bitmap.createBitmap(bitmap,50,50,100,100);
      imgControllo.setImageBitmap(newBmp);
      break;
     
      
    }
    return true;
   }
  };
  imageView.setOnTouchListener(onTouchListener);
Questo codice prende la bitmap e, dopo lo spostamento calcolato a partire dall'angolo superiore sinistro della bitmap, calcola il ritaglio da praticare nella bitmap in relazione allo spostamento, ne crea una nuova bitmap e la pone nell'ImageView di controllo.
Ecco: prima dello spostamento:



E dopo lo spostamento con ritaglio e copia nella seconda ImageView.



Bene.


Ecco, ho creato un codice che permette di individuare le coordinate della bitmap sottostante.
Me lo copio qui, grezzo grezzo e con residui di un codice precedente che resta inutilizzato, in modo da poter attingere ad esso in caso di eventuali vuoti di memoria nella riscrittura di un codice fatto meglio
public class MainActivity extends Activity {
 float X;
 float Y;
 float currentX, currentY;

 ImageView imageView;
 ImageView imageView2;
 RelativeLayout mainLayout;
 RelativeLayout layout;
 Bitmap bitmap;
 Matrix matrix;
 ImageView imgControllo;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  
  
  mainLayout=(RelativeLayout)findViewById(R.id.mainLayout);
  
  int LayLeft, LayTop, LayWidth, LayHeight;
  int ImgLeft, ImgTop, ImgWidth, ImgHeight;
  LayLeft=0;
  LayTop=0;
  LayWidth=100;
  LayHeight=100;
  
  ImgLeft=0;
  ImgTop=0;
  

  
  //CREAZIONE DEL LAYOUT
  layout=new RelativeLayout(this);
  BitmapDrawable sfondo=(BitmapDrawable)this.getResources().getDrawable(R.drawable.cartellanuova);
  layout.setBackground(sfondo);
  
  //settaggio dei parametri
  LayoutParams lParams=new LayoutParams(LayWidth,LayHeight);
  lParams.leftMargin=LayLeft;
  lParams.topMargin=LayTop;
  layout.setLayoutParams(lParams);
  
  
  //CREAZIONE DELL'IMMAGINE
  imageView =new ImageView(this);
  bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.facciadaculo);
  int larghezza=bitmap.getWidth();
  int altezza=bitmap.getHeight();
  
 
  
  
  
  LayoutParams params=new LayoutParams(100,100);
  imageView.setLayoutParams(params);
  imageView.setScaleType(ScaleType.CENTER);
  
  
  
  bitmap=Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), 
    bitmap.getHeight(),matrix, false);
  imageView.setImageBitmap(bitmap);
  
  imageView.setBackgroundColor(Color.BLACK);
  
  mainLayout.addView(imageView);
  
  imgControllo=new ImageView(this);
  LayoutParams p=new LayoutParams(100,100);
  p.leftMargin=10;
  p.topMargin=200;
  imgControllo.setLayoutParams(p);
  imgControllo.setBackgroundColor(Color.BLACK);
  mainLayout.addView(imgControllo);
  
  OnTouchListener onTouchListener=new View.OnTouchListener() {
   Matrix matrix=imageView.getImageMatrix();
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    ((ImageView)v).getImageMatrix().invert(matrix);
    switch(event.getAction()){
     case MotionEvent.ACTION_DOWN:
      X=event.getX();
      Y=event.getY();
      float[] pts={0f,0f};
        
      
      matrix.mapPoints(pts);
      Log.v(""+pts[0],""+pts[1]);
      break;
    }
      
     
    
    return true;
   }
  };
  imageView.setOnTouchListener(onTouchListener);
  
 }
 

 
 @Override
 public void onWindowFocusChanged(boolean hasFocus){
  super.onWindowFocusChanged(hasFocus);
  Log.v("LARGHEZZA DI IMAGEVIEW",""+imageView.getWidth());
  Log.v("ALTEZZA DI IMAGEVIEW",""+imageView.getHeight());
 }
 
}

lunedì 18 aprile 2016

Dimensioni di una bitmap e della ImageView che la contiene

Prendo l'immagine e ne rilevo le dimensioni:
  Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.anguria);
  Log.v(""+bitmap.getWidth(),""+bitmap.getHeight());
Ottengo
04-18 14:40:04.976: V/408(4740): 313
408 e 313.

Metto la bitmap in una ImageView.
  ImageView imageView =new ImageView(this);

  Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.anguria);
  Log.v(""+bitmap.getWidth(),""+bitmap.getHeight());
  
  imageView.setImageBitmap(bitmap);
  mainLayout.addView(imageView);
La ImageView mi viene abbastanza grande:



Siamo sicuri che ImageView abbia le stesse dimensioni della Bitmap?
Vediamole...
  ImageView imageView =new ImageView(this);

  Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.anguria);
  Log.v(""+bitmap.getWidth(),""+bitmap.getHeight());
  
  imageView.setImageBitmap(bitmap);
  Log.v(""+imageView.getWidth(),""+imageView.getHeight());
  mainLayout.addView(imageView);
04-18 15:47:26.523: V/408(5881): 313
04-18 15:47:26.524: V/0(5881): 0

Così facendo, ottengo come risultato 0 e 0.
Il motivo è che fino a onResume non è stata ancora dispiegata "materialmente" la ImageView, e quindi bisogna overridare l'evento onWindowFocusChanged, a quanto leggo...

Proviamo:
  Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.anguria);
  Log.v(""+bitmap.getWidth(),""+bitmap.getHeight());
  
  imageView.setImageBitmap(bitmap);
  mainLayout.addView(imageView);
 }
 
 @Override
 public void onWindowFocusChanged(boolean hasFocus){
  super.onWindowFocusChanged(hasFocus);
  Log.v(""+imageView.getWidth(),""+imageView.getHeight());
 }
04-18 15:50:18.327: V/408(5974): 313

.....

04-18 15:50:18.537: V/408(5974): 313

Per avere la prova, faccio di meglio:
  imageView =new ImageView(this);

  Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.anguria);
  Log.v("LARGHEZZA DELLA BITMAP",""+bitmap.getWidth());
  Log.v("ALTEZZA DELLA BITMAP",""+bitmap.getHeight());
  
  imageView.setImageBitmap(bitmap);
  mainLayout.addView(imageView);
 }
 
 @Override
 public void onWindowFocusChanged(boolean hasFocus){
  super.onWindowFocusChanged(hasFocus);
  Log.v("LARGHEZZA DI IMAGEVIEW",""+imageView.getWidth());
  Log.v("ALTEZZA DI IMAGEVIEW",""+imageView.getHeight());
 }
04-18 15:55:33.902: V/LARGHEZZA DELLA BITMAP(6021): 408
04-18 15:55:33.910: V/ALTEZZA DELLA BITMAP(6021): 313

.....

04-18 15:55:34.016: V/LARGHEZZA DI IMAGEVIEW(6021): 408
04-18 15:55:34.016: V/ALTEZZA DI IMAGEVIEW(6021): 313

Ed è così confermato che le dimensioni della ImageView sono le stesse della bitmap in essa contenuta.

lunedì 11 gennaio 2016

Esercizio di riscrittura del codice che carica un'immagine scalata dalla memoria in una ImageView.

Ricostruire un'applicazione che inserisca in una GridView immagini dalla memoria, con etichetta e categoria.

Per prima cosa, creo un tipo che contenga i tre membri Path, Etichetta e Categoria.
class JImmagine{
 public String Path;
 public String Etichetta;
 public String Categoria;
}
Adesso inserisco un pulsante che prenda l'immagine dalla memoria e mi crei una bitmap da inserire in una ImageView in un thread separato mediante AsyncTask.
Sull'Activity metto un Button e una ImageView e poi scrivo il codice...
public class MainActivity extends Activity {
 
 Button button;
 ImageView imageView;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  setContentView(R.layout.activity_main);
  
  button=(Button)findViewById(R.id.button1);
  imageView=(ImageView)findViewById(R.id.imageView1);
  
  button.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    Intent intent=new Intent();
    intent.setAction(Intent.ACTION_PICK);
    intent.setData(Uri.parse("content://media/external/images/media"));
    startActivityForResult(intent,0);
    
   }
  });
  

 }
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data){
  if(resultCode==RESULT_OK){
   BitmapFactory.Options opzioni=new BitmapFactory.Options();
   opzioni.inJustDecodeBounds=true;
   BitmapFactory.decodeFile(getPathFromUri(data.getData()), opzioni);
   int fattore=1;
   while(opzioni.outHeight/fattore>100 && opzioni.outWidth/fattore>100){
    fattore*=2;
   }
   opzioni.inSampleSize=fattore;
   opzioni.inJustDecodeBounds=false;
   Bitmap bitmap=BitmapFactory.decodeFile(getPathFromUri(data.getData()));
   imageView.setImageBitmap(bitmap);
   
  }
 }
 
 private String getPathFromUri(Uri uri){
  Cursor crs=getContentResolver().query(uri, null, null, null, null);
  int indice=crs.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
  crs.moveToFirst();
  String s=crs.getString(indice);
  crs.close();
  return s;
 }
Ecco, ho scritto di getto il codice che, a parte un errore di distrazione per non aver scritto crs.moveToFirst() mi comprometteva il risultato, ma l'ho individuato e corretto subito.
Funziona.
Ora, però, devo usare la mia classe JImmagine.
Per farlo, devo però avere due controlli per l'immissione dei dati Etichetta e Categoria.

Su questi, ricordo di aver trovato alcuni suggerimenti per far sì che, anche in modalità Landscape, l'activity restasse visibile...
E quindi è il caso di ripassare il tutto, dando magari anche uno sguardo ad altri tipi di layout...

domenica 10 gennaio 2016

Esercizio sull'elaborazione di un'immagine mediante AsyncTask.


Un nuovo esercizio di scrittura per un codice che ponga in un'ImageView un'immagine presa dal contenuto della memoria dello smartphone, elaborando l'immagine al di fuori dell'UI mediante AsyncTask.
public class MainActivity extends Activity {
 
 ImageView immagine;
 Button button;
 Intent intent;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  setContentView(R.layout.activity_main);
  immagine=(ImageView)findViewById(R.id.imageView1);
  button=(Button)findViewById(R.id.button1);
  intent=new Intent();
  intent.setAction(Intent.ACTION_PICK);
  intent.setData(Uri.parse("content://media/external/images/media"));
  
  button.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    startActivityForResult(intent,0);
    
   }
  });
  
  
 }
 
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data){
  if(resultCode==RESULT_OK){
   asyncTask async=new asyncTask(immagine);
   async.execute(getPathFromUri(data.getData()));
   
  }
 }
 
 private String getPathFromUri(Uri uri){
  Cursor crs=getContentResolver().query(uri, null, null, null, null);
  crs.moveToFirst();
  int indice=crs.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
  String s=crs.getString(indice);
  crs.close();
  return s;
  
 }
 
 class asyncTask extends AsyncTask<String,Void,Bitmap>{

  WeakReference<ImageView> reference;
  public asyncTask(ImageView img){
   reference=new WeakReference<ImageView>(img);
  }
  @Override
  protected Bitmap doInBackground(String... params) {
   BitmapFactory.Options opzioni=new BitmapFactory.Options();
   opzioni.inJustDecodeBounds=true;
   BitmapFactory.decodeFile(params[0],opzioni);
   int fattore=1;
   while(opzioni.outWidth/fattore>20 && opzioni.outWidth/fattore>20){
    fattore*=2;
   }
   opzioni.inJustDecodeBounds=false;
   opzioni.inSampleSize=fattore;
   Bitmap bmp=BitmapFactory.decodeFile(params[0],opzioni);
   return bmp;
  }
  
  @Override
  protected void onPostExecute(Bitmap bmp){
   if(bmp!=null && reference!=null){
    ImageView immagine=(ImageView)reference.get();
    if(immagine!=null){
     immagine.setImageBitmap(bmp);
    }
   }
  }

  

 } 
Funziona, funziona...

domenica 3 gennaio 2016

Codici per impostare l'immagine di una view ImageView da Uri, da path e da risorse.

Esercizio: riscrivere il codice per impostare l'immagine di una ImageView a partire da un'immagine salvata in memoria, sia per mezzo dell'URI sia per mezzo del path, sia da risorse.

Con l'URI:
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  setContentView(R.layout.activity_main);
  

  immagine=(ImageView)findViewById(R.id.imageView1);
  
  Intent intent=new Intent();
  intent.setAction(Intent.ACTION_PICK);
  intent.setData(Uri.parse("content://media/external/images/media"));
  startActivityForResult(intent, 0);
 }

...

 protected void onActivityResult(int requestCode, int resultCode, Intent data){
  if(resultCode==RESULT_OK){
   immagine.setImageURI(data.getData());
  }
 }
E fin qui è abbastanza facile...

Adesso facciamo mediante il Path, che dobbiamo andare a risolvere mediante il metodo getContentResolver().query.

@Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  setContentView(R.layout.activity_main);
  

  immagine=(ImageView)findViewById(R.id.imageView1);
  
  Intent intent=new Intent();
  intent.setAction(Intent.ACTION_PICK);
  intent.setData(Uri.parse("content://media/external/images/media"));
  startActivityForResult(intent, 0);
 }
 
 protected void onActivityResult(int requestCode, int resultCode, Intent data){
  if(resultCode==RESULT_OK){
   Bitmap bmp=BitmapFactory.decodeFile(getPathFromUri(data.getData()));
   immagine.setImageBitmap(bmp);
  }
 }
 
  

 public String getPathFromUri(Uri uri){
  Cursor cursor = getContentResolver().query(uri, null, null, null, null);
  cursor.moveToFirst();
  int indice=cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
  String stringa=cursor.getString(indice);
  return stringa;
  
 }
Bene. Funziona!

Adesso dalle risorse:
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  setContentView(R.layout.activity_main);
  

  immagine=(ImageView)findViewById(R.id.imageView1);
  

 
  immagine.setImageResource(R.drawable.faciadecul);
  
 }