JavascriptProva

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

mercoledì 18 maggio 2016

Analisi delle trasformazioni della Matrix.

Lettura di una Matrix.
       float[] values=new float[9];
       matrix.setTranslate(deltaX, deltaY);
       matrix.getValues(values);
       for(int i=0;i<9;i++){
        Log.e("VALORE",""+values[i]);
       }
Vediamo cosa viene fuori...

Ecco: analizziamo...

Movimento da sinistra a destra:
05-18 11:20:29.847: E/VALORE0(2504): 1.0
05-18 11:20:29.848: E/VALORE1(2504): 0.0
05-18 11:20:29.848: E/VALORE2(2504): -29.622559
05-18 11:20:29.848: E/VALORE3(2504): 0.0
05-18 11:20:29.848: E/VALORE4(2504): 1.0
05-18 11:20:29.848: E/VALORE5(2504): -15.548462
05-18 11:20:29.849: E/VALORE6(2504): 0.0
05-18 11:20:29.849: E/VALORE7(2504): 0.0
05-18 11:20:29.849: E/VALORE8(2504): 1.0
05-18 11:20:29.886: E/VALORE0(2504): 1.0
05-18 11:20:29.886: E/VALORE1(2504): 0.0
05-18 11:20:29.887: E/VALORE2(2504): -27.967407
05-18 11:20:29.887: E/VALORE3(2504): 0.0
05-18 11:20:29.887: E/VALORE4(2504): 1.0
05-18 11:20:29.887: E/VALORE5(2504): -15.548462
05-18 11:20:29.887: E/VALORE6(2504): 0.0
05-18 11:20:29.887: E/VALORE7(2504): 0.0
05-18 11:20:29.888: E/VALORE8(2504): 1.0
05-18 11:20:29.903: E/VALORE0(2504): 1.0
05-18 11:20:29.903: E/VALORE1(2504): 0.0
05-18 11:20:29.912: E/VALORE2(2504): -26.961212
05-18 11:20:29.912: E/VALORE3(2504): 0.0
05-18 11:20:29.912: E/VALORE4(2504): 1.0
05-18 11:20:29.912: E/VALORE5(2504): -15.548462
05-18 11:20:29.912: E/VALORE6(2504): 0.0
05-18 11:20:29.912: E/VALORE7(2504): 0.0
05-18 11:20:29.912: E/VALORE8(2504): 1.0
05-18 11:20:29.928: E/VALORE0(2504): 1.0
05-18 11:20:29.928: E/VALORE1(2504): 0.0
05-18 11:20:29.929: E/VALORE2(2504): -25.948822
05-18 11:20:29.936: E/VALORE3(2504): 0.0
05-18 11:20:29.936: E/VALORE4(2504): 1.0
05-18 11:20:29.939: E/VALORE5(2504): -15.548462
05-18 11:20:29.940: E/VALORE6(2504): 0.0
05-18 11:20:29.940: E/VALORE7(2504): 0.0
05-18 11:20:29.940: E/VALORE8(2504): 1.0
Me li rappresento in forma di matrice:
1   0   -29.622559
0   1   -15.548462
0   0    1


1   0   -27.967407
0   1   -15.548462
0   0    1


1   0   -26.961212
0   1   -15.548462
0   0    1


1   0   -25.948822
0   1   -15.548462
0   0    1
Eccellente!!! Dalla disposizione dei numeri delle matrici deduco che si tratti proprio di una matrice di traslazione! E' evidente!
Si tratta, infatti, del codice che ho creato io per il trascinamento di un'immagine, basato sulla manipolazione della Matrix!

Ora posso analizzare le modificazioni della Matrix in relazione a scalature e traslazioni, in modo da regolarmi bene per creare gli opportuni prodotti fra matrici, dato che il prodotto fra matrici non è dotato della proprietà commutativa!

martedì 10 maggio 2016

Impostare i limiti dello scorrimento di un'immagine senza far ricorso alla Matrix.

Cerchiamo di capire questa formula del Math.max.

 x = Math.max(AXIS_X_MIN, Math.min(x, AXIS_X_MAX - curWidth));
 y = Math.max(AXIS_Y_MIN + curHeight, Math.min(y, AXIS_Y_MAX));
AXIS_X_MIN sarebbe il numero minimo sull'asse delle X. La funzione Math.max sceglie il massimo fra questo valore minimo e un altro valore, che è Math.min(x, AXIS_X_MAX - curWidth).
Dobbiamo interpretare questo, adesso.
Sceglie il valore minimo fra la x corrente e la larghezza, credo, della larghezza di un rettangolo.
Se la x corrente è bassa, viene scelta come valore dalla funzione Math.min.
Se la x comincia a crescere, quando raggiunge il valore di AXIS_X_MAX - curWidth non viene più scelta, ma viene scelta la X.
Questo potrebbe essere un modo per limitare lo scorrimento di un'immagine in una finestra senza far ricorso alle matrici come ho fatto io...

Se infatti io imposto che x è uguale a x se però la x è inferiore a un certo valore, altrimenti è uguale a quel valore, il problema dovrebbe essere risolto in modo molto semplice e senza scomodare matrici varie...

Math.max invece serve per rendere la x uguale a x nel caso in cui questa sia superiore al valore minimo, ossia AXIS_X_MIN.
Ci potrebbe essere un problema nel caso in cui la x sia maggiore del valore massimo considerato, perché verrebbe scelto questo, ma è un falso problema, perché questo è considerato solo se la x tende a eccederlo.

Ho capito la formula!

Ora provo a costruire una limitazione dei movimenti semplicemente per mezzo di quella funzione che non coinvolgeva la Matrix ma era molto più semplice.


   OnTouchListener onTouchListener =new View.OnTouchListener() {
   
    int X,Y;
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    
    int action=event.getAction();
    switch(action & MotionEvent.ACTION_MASK){
    case MotionEvent.ACTION_DOWN:
     X=(int)event.getX();
     Y=(int)event.getY();
     
     break;
    case MotionEvent.ACTION_MOVE:
     int currentX=(int)event.getX();
     int currentY=(int)event.getY();
     v.scrollBy(X-currentX, Y-currentY);
     X=currentX;
     Y=currentY;
     break;
    }
    return true;
   }
  };
  imageView.setOnTouchListener(onTouchListener);
Ecco, questo è il semplicissimo modellino di un'immagine scrollabile.
Però ora dobbiamo provare a metterci dei limiti secondo quanto visto con la formula di cui sopra.

   OnTouchListener onTouchListener =new View.OnTouchListener() {
   int fetta=50;
   int X,Y;
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    
    int action=event.getAction();
    switch(action & MotionEvent.ACTION_MASK){
    case MotionEvent.ACTION_DOWN:
     X=(int)event.getX();
     Y=(int)event.getY();
     
     break;
    case MotionEvent.ACTION_MOVE:
     int currentX=(int)Math.max(fetta,Math.min(event.getX(),v.getWidth()-fetta));
     int currentY=(int)Math.max(fetta,Math.min(event.getY(),v.getWidth()-fetta));
     v.scrollBy(X-currentX, Y-currentY);
     X=currentX;
     Y=currentY;
     break;
    }
    return true;
   }
  };
  imageView.setOnTouchListener(onTouchListener);
Funziona egregiamente!
Studiamo lo scaling, adesso...

private class ScaleListener 
        extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        mScaleFactor *= detector.getScaleFactor();

        // Don't let the object get too small or too large.
        mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));

        invalidate();
        return true;
    }
}
che cosa è mScaleFactor?
Andiamo a cercarci la definizione...
private float mScaleFactor = 1.f;
che non aggiunge niente... vediamo come viene usato.
 canvas.scale(mScaleFactor, mScaleFactor);
Ora, sul canvas sono ancora poco esperto.
Ma sarebbe il fattore scala...

Come posso usarlo qui?
Proviamo...

Con una matrix è l'unico modo che mi venga in mente...

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.

Scrolling di un'immagine per mezzo di Matrix (mio codice)

Questo è il codice per mezzo del quale sono riuscito a imporre dei limiti allo scorrimento di un'immagine all'interno di una finestra.
Me lo annoto, e poi cerco, se possibile, di apporre dei perfezionamenti.
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);
  
  
 }

} 

giovedì 28 aprile 2016

Traslazione di un'immagine e copia di essa su un'altra ImageView, basata sulle matrici (promemoria codice)

Torniamo allo scrolling delle immagini.
Questo è il codice che ho preso da uno dei miei progetti-laboratorio:
public class MainActivity extends Activity {

 float[] pts;
 RelativeLayout mainLayout;
 ImageView imageView;
 ImageView imgControllo;
 Bitmap bitmap;
 float X, Y;
 float currentX, currentY;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  mainLayout=(RelativeLayout)findViewById(R.id.mainLayout);
  
  
  final ImageView imageView=new ImageView(this);
  imageView.setScaleType(ScaleType.MATRIX);
  bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.verticalimagetest);
  LayoutParams params=new LayoutParams(300,300);
  imageView.setLayoutParams(params);
  imageView.setImageBitmap(bitmap);
  imageView.setBackgroundColor(Color.GREEN);
  mainLayout.addView(imageView);
 
  final ImageView imgControllo=new ImageView(this);
  imgControllo.setScaleType(ScaleType.FIT_CENTER);
  bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.verticalimagetest);
  LayoutParams params2=new LayoutParams(100,200);
  params2.leftMargin=500;
  params2.topMargin=100;
  imgControllo.setLayoutParams(params2);
  imgControllo.setBackgroundColor(Color.BLACK);
  mainLayout.addView(imgControllo);
  
  Button button=new Button(this);
  LayoutParams bttParams=new LayoutParams(150,50);
  bttParams.leftMargin=300;
  bttParams.topMargin=100;
  button.setLayoutParams(bttParams);
  button.setText("Crea");
  mainLayout.addView(button);
  button.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    
    imageView.destroyDrawingCache();
    imageView.buildDrawingCache();
    Bitmap bmp=imageView.getDrawingCache();
    imgControllo.setImageBitmap(bmp);
    
   }
  });
  
  OnTouchListener onTouchListener=new View.OnTouchListener() {
   Matrix matrice=new Matrix();
   Matrix inversa=new Matrix();
   
   @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();
     pts=new float[]{0,0};
     imageView.getImageMatrix().invert(inversa);
     inversa.mapPoints(pts);
     matrice.setTranslate(-pts[0]+currentX-X, -pts[1]+currentY-Y);
     imageView.setImageMatrix(matrice);
     X=currentX;
     Y=currentY;
     imageView.destroyDrawingCache();
     imageView.buildDrawingCache();
     Bitmap bmp=imageView.getDrawingCache();
     imgControllo.setImageBitmap(bmp);
     
     break;
    }
    return true;
   }
   
  };
  imageView.setOnTouchListener(onTouchListener);
  
 }

}
Questo è basato sulle matrici, ossia la traslazione di un'immagine avviene per mezzo di una Matrix.
Ma si può fare anche in modo diverso...

venerdì 22 aprile 2016

Codice per il trascinamento di un'immagine da una ImageView mediante trasformazioni di Matrix.

Ho trovato il modo di ottenere un trascinamento dell'immagine mediante le trasformazioni della Matrix in modo da tener conto del punto dell'immagine nel quale mi trovo, allo scopo di poter ritagliare un frammento dell'immagine stessa.
Ecco il codice (da salvare come promemoria standard cui ricorrere in caso di necessità di ripasso)
  OnTouchListener onTouchListener=new View.OnTouchListener() {
   Matrix matrice=new Matrix();
   Matrix inversa=new Matrix();
   
   @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();
     pts=new float[]{0,0};
     imageView.getImageMatrix().invert(inversa);
     inversa.mapPoints(pts);
     matrice.setTranslate(-pts[0]+currentX-X, -pts[1]+currentY-Y);
     imageView.setImageMatrix(matrice);
     X=currentX;
     Y=currentY;
     
     break;
    }
    return true;
   }
   
  };
  imageView.setOnTouchListener(onTouchListener);

lunedì 18 aprile 2016

Studi di ridimensionamento di immagini con Matrix

Adesso ridimensiono la bitmap e poi vedo se la ImageView che la contiene si riduce di conseguenza.

  imageView =new ImageView(this);

  Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.anguria);
  bitmap=Bitmap.createScaledBitmap(bitmap, 100, 100, false);
  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:59:10.215: V/LARGHEZZA DELLA BITMAP(6108): 100
04-18 15:59:10.216: V/ALTEZZA DELLA BITMAP(6108): 100

.....

04-18 15:59:10.434: V/LARGHEZZA DI IMAGEVIEW(6108): 100
04-18 15:59:10.434: V/ALTEZZA DI IMAGEVIEW(6108): 100

Ho ridotto l'immagine senza rispetto per le proporzioni.
Ma ricordo adesso che si può usare Matrix per scalare le immagini.
Ciò può essere molto utile, anziché calcolare il rapporto larghezza/altezza e agire di conseguenza...

Vediamo...

  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());
  Matrix matrix=new Matrix();
  matrix.postScale(.5f,.5f);
  bitmap=Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
  Log.v("LARGHEZZA DELLA BITMAP DOPO MATRIX",""+bitmap.getWidth());
  Log.v("ALTEZZA DELLA BITMAP DOPO MATRIX",""+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 19:01:38.411: V/LARGHEZZA DELLA BITMAP(6466): 408
04-18 19:01:38.411: V/ALTEZZA DELLA BITMAP(6466): 313
04-18 19:01:38.412: V/ALTEZZA DELLA BITMAP DOPO MATRIX(6466): 157

.....

04-18 19:01:39.289: V/LARGHEZZA DI IMAGEVIEW(6466): 204
04-18 19:01:39.290: V/ALTEZZA DI IMAGEVIEW(6466): 157

Perfetto! La bitmap si è ridimensionata e la ImageView con lei.


Ora voglio portare la bitmap a una larghezza di 100.
Calcolo il rapporto fra 100 e la larghezza della bitmap...


  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());
  float Ratio=100f/(float)bitmap.getWidth();
  
  Matrix matrix=new Matrix();
  matrix.postScale(Ratio,Ratio);
  bitmap=Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
  Log.v("LARGHEZZA DELLA BITMAP DOPO MATRIX",""+bitmap.getWidth());
  Log.v("ALTEZZA DELLA BITMAP DOPO MATRIX",""+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());
 }
E vediamo le misure:
04-18 19:08:39.152: V/LARGHEZZA DELLA BITMAP(6512): 408
04-18 19:08:39.152: V/ALTEZZA DELLA BITMAP(6512): 313
04-18 19:08:39.153: V/LARGHEZZA DELLA BITMAP DOPO MATRIX(6512): 100
04-18 19:08:39.153: V/ALTEZZA DELLA BITMAP DOPO MATRIX(6512): 77

.....

04-18 19:08:39.562: V/LARGHEZZA DI IMAGEVIEW(6512): 100
04-18 19:08:39.562: V/ALTEZZA DI IMAGEVIEW(6512): 77

Perfetto! La larghezza è stata portata a 100!

Ora voglio che l'altezza sia pari a 100:
  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());
  float Ratio=100f/(float)bitmap.getHeight();
  
  Matrix matrix=new Matrix();
  matrix.postScale(Ratio,Ratio);
  bitmap=Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
  Log.v("LARGHEZZA DELLA BITMAP DOPO MATRIX",""+bitmap.getWidth());
  Log.v("ALTEZZA DELLA BITMAP DOPO MATRIX",""+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 19:10:26.931: V/LARGHEZZA DELLA BITMAP(6601): 408
04-18 19:10:26.931: V/ALTEZZA DELLA BITMAP(6601): 313
04-18 19:10:26.937: V/LARGHEZZA DELLA BITMAP DOPO MATRIX(6601): 130
04-18 19:10:26.938: V/ALTEZZA DELLA BITMAP DOPO MATRIX(6601): 100

.....

04-18 19:10:27.114: V/LARGHEZZA DI IMAGEVIEW(6601): 130
04-18 19:10:27.114: V/ALTEZZA DI IMAGEVIEW(6601): 100

Perfetto!
Dunque, se un'immagine è orizzontale, la misura da riportare a 100 sarà la larghezza, mentre se è verticale la misura sarà l'altezza.
Potremo così costringere un'immagine a stare nei limiti che vogliamo.
Ma se ho un'immagine orizzontale, che riduco a 100 di larghezza ma voglio che non occupi più di una certa dimensione in altezza, ossia ho due limiti, come mi metto?
Se porto direttamente l'altezza a valori inferiori al limite verticale, potrei avere ancora una larghezza superiore a 100.
Se porto la larghezza a valori inferiori a 100 potrei avere ancora un'altezza superiore al secondo limite.
Così, per le immagini orizzontali bisogna prima rapportarle a 100 e poi al secondo limite.


Iniziamo a ridimensionare le immagini secondo la larghezza o l'altezza a seconda che siano rispettivamente orizzontali o verticali.
Facciamo conto che il limite orizzontale sia 100 e quello verticale di 50.
Innanzitutto distinguiamo se l'immagine è orizzontale o verticale. Se è perfettamente quadrata può rientrare nel campo di quelle verticali.

  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());
  
  int larghezza=bitmap.getWidth();
  int altezza=bitmap.getHeight();
  
  
  float Ratio;
  if(altezza>=larghezza) Ratio=50f/(float)bitmap.getHeight();
  else Ratio=100f/(float)bitmap.getWidth();
 
  
  Matrix matrix=new Matrix();
  matrix.postScale(Ratio,Ratio);
  bitmap=Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
  Log.v("LARGHEZZA DELLA BITMAP DOPO MATRIX",""+bitmap.getWidth());
  Log.v("ALTEZZA DELLA BITMAP DOPO MATRIX",""+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());
 }
Ecco: questo codice stabilisce un limite di larghezza 100 per le immagini orizzontali, mentre stabilisce un limite di altezza 50 per le immagini verticali e quadrate.
Lo provo dapprima con l'immagine orizzontale "anguria", quindi con l'immagine verticale "torre": Con "anguria", immagine orizzontale:
04-18 19:26:51.062: V/LARGHEZZA DELLA BITMAP(6785): 408
04-18 19:26:51.062: V/ALTEZZA DELLA BITMAP(6785): 313

04-18 19:26:51.062: V/LARGHEZZA DELLA BITMAP DOPO MATRIX(6785): 100
04-18 19:26:51.062: V/ALTEZZA DELLA BITMAP DOPO MATRIX(6785): 77

04-18 19:26:51.255: V/LARGHEZZA DI IMAGEVIEW(6785): 100
04-18 19:26:51.255: V/ALTEZZA DI IMAGEVIEW(6785): 77
Mi ha ridotto l'immagine orizzontale a una larghezza di 100 (con un'altezza di 77).

Con "torre", immagine verticale:
04-18 19:29:13.569: V/LARGHEZZA DELLA BITMAP(6832): 591
04-18 19:29:13.570: V/ALTEZZA DELLA BITMAP(6832): 888

04-18 19:29:13.570: V/LARGHEZZA DELLA BITMAP DOPO MATRIX(6832): 33
04-18 19:29:13.570: V/ALTEZZA DELLA BITMAP DOPO MATRIX(6832): 50

04-18 19:29:13.769: V/LARGHEZZA DI IMAGEVIEW(6832): 33
04-18 19:29:13.770: V/ALTEZZA DI IMAGEVIEW(6832): 50
Mi ha ridotto l'immagine verticale a un'altezza di 50 (con larghezza pari a 33).
Ora, però, io voglio che per l'immagine orizzontale anche l'altezza abbia dei limiti, ossia che sia al massimo di 50.
Come fare?
Proviamo...
  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 bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.anguria);
  Log.v("LARGHEZZA DELLA BITMAP",""+bitmap.getWidth());
  Log.v("ALTEZZA DELLA BITMAP",""+bitmap.getHeight());
  
  int larghezza=bitmap.getWidth();
  int altezza=bitmap.getHeight();
  
  
  float Ratio;
  if(altezza>=larghezza) Ratio=50f/(float)bitmap.getHeight();
  else Ratio=100f/(float)bitmap.getWidth();
 
  
  Matrix matrix=new Matrix();
  matrix.postScale(Ratio,Ratio);
  bitmap=Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
  Log.v("LARGHEZZA DELLA BITMAP DOPO MATRIX",""+bitmap.getWidth());
  Log.v("ALTEZZA DELLA BITMAP DOPO MATRIX",""+bitmap.getHeight());
  
  if(bitmap.getHeight()>50){
   Ratio=50f/(float)bitmap.getHeight();
   Log.v("RATIO",""+Ratio);
   matrix=new Matrix();
   matrix.postScale(Ratio, Ratio);
   bitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(), bitmap.getHeight(),matrix,false);
   Log.v("LARGHEZZA DELLA BITMAP DOPO SECONDA MATRIX",""+bitmap.getWidth());
   Log.v("ALTEZZA DELLA BITMAP DOPO SECONDA MATRIX",""+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());
 }
Ecco.
La provo con l'immagine anguria che è orizzontale con poca differenza fra altezza e larghezza:
04-18 20:05:06.598: V/LARGHEZZA DELLA BITMAP(7254): 408
04-18 20:05:06.598: V/ALTEZZA DELLA BITMAP(7254): 313

04-18 20:05:06.598: V/LARGHEZZA DELLA BITMAP DOPO MATRIX(7254): 100
04-18 20:05:06.598: V/ALTEZZA DELLA BITMAP DOPO MATRIX(7254): 77

04-18 20:05:06.600: V/RATIO(7254): 0.64935064

04-18 20:05:06.603: V/LARGHEZZA DELLA BITMAP DOPO SECONDA MATRIX(7254): 65
04-18 20:05:06.604: V/ALTEZZA DELLA BITMAP DOPO SECONDA MATRIX(7254): 50
Dopo aver ridotto l'immagine orizzontale a 100, questa ha un'altezza di 77, che è eccessiva rispetto al limite verticale di 50. Calcola nuovamente il rapporto e la riduce ulteriormente fino a un'altezza di 50.

La provo adesso con l'immagine torre che è verticale:
04-18 20:07:41.595: V/LARGHEZZA DELLA BITMAP(7302): 591
04-18 20:07:41.595: V/ALTEZZA DELLA BITMAP(7302): 888

04-18 20:07:41.596: V/LARGHEZZA DELLA BITMAP DOPO MATRIX(7302): 33
04-18 20:07:41.596: V/ALTEZZA DELLA BITMAP DOPO MATRIX(7302): 50

04-18 20:07:41.726: V/LARGHEZZA DI IMAGEVIEW(7302): 33
04-18 20:07:41.726: V/ALTEZZA DI IMAGEVIEW(7302): 50
Non va oltre la prima riduzione all'altezza di 50.

La provo adesso con l'immagine chiave che è orizzontale più stretta della precedente orizzontale:
04-18 20:09:23.188: V/LARGHEZZA DELLA BITMAP(7348): 406
04-18 20:09:23.188: V/ALTEZZA DELLA BITMAP(7348): 175

04-18 20:09:23.188: V/LARGHEZZA DELLA BITMAP DOPO MATRIX(7348): 100
04-18 20:09:23.193: V/ALTEZZA DELLA BITMAP DOPO MATRIX(7348): 43

04-18 20:09:23.401: V/LARGHEZZA DI IMAGEVIEW(7348): 100
04-18 20:09:23.402: V/ALTEZZA DI IMAGEVIEW(7348): 43
In questo caso, con la riduzione a 100 l'altezza è già sotto il limite verticale di 50 e quindi l'immagine non necessita di ulteriori riduzioni.
Tutto ciò è quanto era nelle mie intenzioni!

Adesso bisogna studiare il posizionamento delle immagini in una View, in relazione al rapporto con una TextView.

venerdì 15 aprile 2016

Matrix

Che cosa è una Matrix?

Proviamo a crearla e usarla come da alcuni esempi.

Ma poi come si usa? Con Bitmap.createBitmap... e com'è questo metodo?

Ecco, ho ricostruito il tutto:
public class MainActivity extends Activity {
 
 ImageView imageView;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  imageView=(ImageView)findViewById(R.id.imageView1);
  
  Matrix matrix=new Matrix();
  matrix.postScale(.1f,1f);
  
  Bitmap bitmap =BitmapFactory.decodeResource(getResources(), R.drawable.lucchiuso);
  
  Bitmap bmp=Bitmap.createBitmap(bitmap,0,0,500,500,matrix,false);
  imageView.setImageBitmap(bmp);
 
 } 
}
In questo caso, impostando come parametri del metodo postScale della Matrix .1 e 1, si ottiene un'immagine fortemente allungata.