Spanish [SOLUCIONADO] Ajustar imagen para que siempre quede proporcionada al crecer

desof

Well-Known Member
Licensed User
Longtime User
Necesitaría una forma de cargar una imagen en un ImageView y que siempre quede proporcionada al rotar el dispositivo y ajustarse su contenedor.
Veo que el control ImageView sólo tiene 3 propiedades
Fill mas o menos logra eso pero sería bueno que al rotar el dispositivo y tener mas espacio pueda crecerlo mas posible sin perder la proporción.
Alguna idea ?
C
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola

Puedes ponerla con el objeto TouchImageView, que te la redimensiona bien y ademas puedes hacer zoom con los dedos.

O bien cargas la imagen en un Bitmap, que si tienes que cargar muchas puedes hacerlo asi:

B4X:
Dim Bitmap1 As Bitmap
Bitmap1.InitializeSample (DirImagen,NombreImagen,25%x,25%y) 
' el 25%x y 25%y son  máximo ancho, máximo alto, con esto ajustas la dimension del bitmap y por lo tanto cargas menos la memoria

' si no es es el caso puedes hacerlo normal
Bitmap1.Initialize(DirImagen,NombreImagen)


Luego pasas a una variables los valores de ancho y alto de la imagen, y calculas la relación, con la relación ya puedes darle los valores que tu quieras.
B4X:
AnchoImagen = Bitmap1.Width
AltoImagen = Bitmap1.Height


Cuando la tengas redimensionada la puedes cargar a tu ImagenView para verla:
B4X:
ImagenView1.Bitmap = Bitmap1

Saludos
 

desof

Well-Known Member
Licensed User
Longtime User
Hola

Puedes ponerla con el objeto TouchImageView, que te la redimensiona bien y ademas puedes hacer zoom con los dedos.

O bien cargas la imagen en un Bitmap, que si tienes que cargar muchas puedes hacerlo asi:

B4X:
Dim Bitmap1 As Bitmap
Bitmap1.InitializeSample (DirImagen,NombreImagen,25%x,25%y)
' el 25%x y 25%y son  máximo ancho, máximo alto, con esto ajustas la dimension del bitmap y por lo tanto cargas menos la memoria

' si no es es el caso puedes hacerlo normal
Bitmap1.Initialize(DirImagen,NombreImagen)


Luego pasas a una variables los valores de ancho y alto de la imagen, y calculas la relación, con la relación ya puedes darle los valores que tu quieras.
B4X:
AnchoImagen = Bitmap1.Width
AltoImagen = Bitmap1.Height


Cuando la tengas redimensionada la puedes cargar a tu ImagenView para verla:
B4X:
ImagenView1.Bitmap = Bitmap1

Saludos

Muchas Gracias ahi lo probaré!!
Estuve viendo TouchImageView y está muy pero muy atractivo de usar !
Pero al parecer no utiliza un Layout existente por que las vistas se generan de forma dinámica. Supongo que tbn se podrá incorporar a un Layout existente y reemplazar un ImageView standar.
 

desof

Well-Known Member
Licensed User
Longtime User
Hola BGSoft ahí lo he implementado y funciona correctamente solo que no estoy seguro de que comprenda muy bien como funciona ....
Si uso esta línea
>> ''Bitmap1.InitializeSample (File.DirAssets,"xxx.jpg",50%x,50%y)
no noto diferencia de si uso esta otra
>> Bitmap1.Initialize(File.DirAssets,"xxx.jpg")

Aunque si he advertido que al ponerle un porcentaje muy pequeño a la línea superior me baja la calidad de la imagen por lo que sería una forma de manejar la resolución mas que el tamaño verdad ?


B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("Layout1")
    Dim Bitmap1 As Bitmap
    ' el 25%x y 25%y son  máximo ancho, máximo alto, con esto ajustas la dimensión del bitmap y por lo tanto cargas menos la memoria
    Bitmap1.InitializeSample (File.DirAssets,"lemos.jpg",50%x,50%y)
    ' si no es es el caso puedes hacerlo normal
    'Bitmap1.Initialize(File.DirAssets,"bosco.jpg")
    Dim AnchoImagen As Double
    Dim AltoImagen As Double
    AnchoImagen = Bitmap1.Width
    AltoImagen = Bitmap1.Height
    ImageView1.Bitmap = Bitmap1
End Sub
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola BGSoft ahí lo he implementado y funciona correctamente solo que no estoy seguro de que comprenda muy bien como funciona ....
Si uso esta línea
>> ''Bitmap1.InitializeSample (File.DirAssets,"xxx.jpg",50%x,50%y)
no noto diferencia de si uso esta otra
>> Bitmap1.Initialize(File.DirAssets,"xxx.jpg")

Aunque si he advertido que al ponerle un porcentaje muy pequeño a la línea superior me baja la calidad de la imagen por lo que sería una forma de manejar la resolución mas que el tamaño verdad ?


B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("Layout1")
    Dim Bitmap1 As Bitmap
    ' el 25%x y 25%y son  máximo ancho, máximo alto, con esto ajustas la dimensión del bitmap y por lo tanto cargas menos la memoria
    Bitmap1.InitializeSample (File.DirAssets,"lemos.jpg",50%x,50%y)
    ' si no es es el caso puedes hacerlo normal
    'Bitmap1.Initialize(File.DirAssets,"bosco.jpg")
    Dim AnchoImagen As Double
    Dim AltoImagen As Double
    AnchoImagen = Bitmap1.Width
    AltoImagen = Bitmap1.Height
    ImageView1.Bitmap = Bitmap1
End Sub

Hola Desof:

El InitializeSample lo que hace es bajar el tamaño interno del bitmap cuando lo cargas, por lo tanto cuanto menor sea el numero, mas pequeño es, y claro bajas la resolución, con un 25%x que es el 25% del ancho del dispositivo movil no notarias la diferencia pero si a nivel de memoria, por eso te comenté que lo puedes emplear si vas a cargar muchas imagenes a la vez, por que al final puede salirte un error de "Out of memory" , por eso te recomendé ese método, si solo vas a cargar una hazlo de la forma habitual, aunque no pasa nada si cargas una con ese método, menos memoria consumiras. Por otro lado ese valor lo puedes poner en lo que quieras, en un entero o en dip . Te lo puse asi por que es mas facil entender como funciona.

Bueno, ahora que ya sabes el tamaño del bitmap, sacar la relacion es facil ya luego la pones de forma que se mantenga aunque gires al pantalla.

Saludos
 

bgsoft

Well-Known Member
Licensed User
Longtime User
En este ejemplo que subo se acomoda correctamente con el dispositivo vertical pero al voltearlo no se ve completa.
Como se podria hacer para que se ajuste tbn ?

Como decia Jack el Destripador; Vayamos por partes :D

He mirado tu código, pero no has puesto nada para sacar la relación de aspecto:
B4X:
  Dim Bitmap1 As Bitmap
   ' el 25%x y 25%y son  máximo ancho, máximo alto, con esto ajustas la dimension del bitmap y por lo tanto cargas menos la memoria
   Bitmap1.InitializeSample (File.DirAssets,"lemos.jpg",100%x,100%y)
   ' si no es es el caso puedes hacerlo normal
   'Bitmap1.Initialize(File.DirAssets,"bosco.jpg")
   Dim AnchoImagen As Double
   Dim AltoImagen As Double
   AnchoImagen = Bitmap1.Width
   AltoImagen = Bitmap1.Height
   ImageView1.Gravity=Gravity.CENTER   
   ImageView1.Bitmap = Bitmap1
Con esto solo pintas la imagen, y como en el LayOut tienes esto:
B4X:
ImageView1.Width=100%x
ImageView1.Left=0
ImageView1.SetTopAndBottom (Label1.Bottom,Button1.Top)
Pues lógico que no salga como quieres.


Te he creado un código rápido que te saca la relación de aspecto y te pinta la imagen en el centro de la pantalla.
Le puedes pasar el maximo ancho y alto de la imagen, si la quieres poner en algun sitio concreto, puedes hacerlo directamente o pasarle en la llamada un top, esto lo desarrollas tu a tu gusto.
La imagen la creo en ejecución y asi la puedes llamar desde donde quieras sin necesitad de crearla en el Designer, si quieres rizar mas el rizo, pásale el evento y asi sabras cuando te pulsan la imagen. Es solo un simple ejemplo para que tu lo desarrolles a tu gusto. Si la imagen la quieres incrustar en un panel o scroll, en vez de hacerlo en el activity, hazlo en tu panel o en tu scroll.
Tambien le puedes pasar la carpeta y el nombre del fichero de la imagen a cargar o simplemente ponerlo en variables globales.

' esto hace la llamada a pintar la imagen:
B4X:
' pasale los valores de ancho y alto que quieras
PintarImagen ( 30%x,30%y)

Esta es la rutina para pintarla
B4X:
Sub PintarImagen (AnchoMaximoQueQueremos As Int,AltoMaximoQueQueremos As Int )
     
   Dim Xi As Long, Yi As Long, XdivY As Double
   Dim Xf As Long, Yf As Long
   Dim LeftImagen , TopImagen As Int   
     
   Dim Bitmap1 As Bitmap
   
  ' ------------- cargar la imagen -----------   
  Try
     Bitmap1.InitializeSample (File.DirAssets,"lemos.jpg",25%x,25%y)  
   Catch
    ' No se pudo cargar la Imagen
    ToastMessageShow("No se pudo cargar la Imagen",True)
    Log("Error de carga del Bitmap1 en PintarImagen")
    Return
   End Try

   
     ' CALCULAR RELACION ASPECTO IMAGEN
     Xi = Bitmap1.Width
     Yi = Bitmap1.Height
     XdivY = Xi / Yi  
     '>1:X>Y / <1:X<Y
     If XdivY >= 1 Then
      Xf = AnchoMaximoQueQueremos
      Yf = Xf / XdivY
     Else
      Yf = AltoMaximoQueQueremos
      Xf = Yf * XdivY
     End If

    ' centrar imagen en pantalla
     LeftImagen=(100%x-Xf)/2  
     TopImagen =(100%y-Yf)/2
   
     Dim ImageView2 As ImageView
     ImageView2.Initialize("")
     ImageView2.Bitmap = Bitmap1
     ImageView2.Gravity = Gravity.FILL
    Activity.AddView(ImageView2,LeftImagen,TopImagen,Xf,Yf)
     ImageView2.Visible = True
    ImageView2.BringToFront

End Sub


Saludos
 

desof

Well-Known Member
Licensed User
Longtime User
Muchisimas Gracias Jesus!!

Ahi lo prové y está perfecto!
Ahora deberé desarrollar una forma para que verifique que el valor (%) pasado como parametro no haga superar a la imagen de la pantalla por que yo a este ejemplo tal como me lo subiste le cambie a un 75 % ambos y en la vista Horizontal me sobrepasa los limites.
Tal vez no me expresé bien pero en este caso en concreto debo ubicar la imagen de forma dinámica y sobre esa imagen calcular las medidas del bitmap para ajustarlo dentro de la vista. Por que en este método uno crea primero el bitmap luego lo ubica.
 
Last edited:

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola

Me alegro que te funcione

Para lo que quieres, es muy facil, mira si la resultante horizontal y vertical es mayor que la pantalla (una vez calculada la relacion), y si lo es le dices que el ancho maximo sea la pantalla. Por separado el ancho y el alto.

Saludos
 
Top