Italian Ridimensionare immagini - dimensioni e qualità (quindi peso)

Luigi S

Active Member
Licensed User
Ho visto che ci sono molti metodi per ridimensionare le immagini (sostanzialmente jpg), ma quelli che ho provato, non ridimensionano molto la qualità e quindi il peso dell'immagine.
Mi trovo a prelevare le immagini dalla memoria del device e soprattutto quelle scattate con la fotocamera interna sono di peso e dimensioni ragguardevoli.
Se avete provato qualcuno dei metodi presenti sul forum o ne avete uno vostro gentilmente potete indicarmelo?
 

Sagenut

Expert
Licensed User
Longtime User
Non ho capito bene la domanda.
Hai bisogno di ridurre il peso di immagini che aggiungerai al tuo progetto (come background e cose simili)?
Oppure hai bisogno di caricare grandi immagini usando meno memoria?
 

udg

Expert
Licensed User
Longtime User
Cerca tinypng tool online che riduce le dimensioni del file immagine senza intaccarne la qualità in modo apprezzabile
 

Sagenut

Expert
Licensed User
Longtime User
Per ridurre di molto il peso di una immagine lasciando fondamentalmente inalterata la qualità puoi usare questo sito:
TinyPNG
Il secondo caso è che se una immagine è molto grande (inteso come dimensione in pixel tipo 4000 x 4000) occuperebbe molta memoria.
Per ridurre tale problema invece che con LoadBitmap devi usare LoadBitmapSample che carica una versione ridotta dell'immagine.

@udg abbiamo risposto in contemporanea. 🤣
 

Sagenut

Expert
Licensed User
Longtime User
LoadBitmapSample riduce la quantità di memoria utilizzata.
Se devi ridurre la dimensione visiva allora forse ti serve il LoadBitmapResize.
 

Luigi S

Active Member
Licensed User
Il LoadBitmapResize l'ho provato riduce le dimensioni ma non mi pare riduca molto il peso, ti risulta?
 

Sagenut

Expert
Licensed User
Longtime User
Per ridurre il peso in memoria usa LoadBitmapSample.
 

Luigi S

Active Member
Licensed User
Ok quindi nella ListView per caricare le immagini uso LoadBitmapSample, mentre quando ne carico una sola a schermo intero uso LoadBitmap, giusto?
 

Sagenut

Expert
Licensed User
Longtime User
Giusto.
 

Luigi S

Active Member
Licensed User
Io ho fatto cosi:
Copio le immagini dalla memoria del telefono che solitamente sono jpg e le metto in una mia cartella rinominandole
Per metterle nella ListView le vado a leggere dalla mia cartella usando LoadBitmapSample impostando 80dipx80dip (al posto di LoadBitmap ed ho ottenuto un buon incremento di velocità)
Per metterne una nella singola vista a tutto schermo uso LoadBitmap, leggendo sempre dalla mia cartella.

Dovrei trasformale in png quando le copio? E come si fa?
 

LucaMs

Expert
Licensed User
Longtime User
Per la velocità di caricamento, se le immagini sono tante, ti converrebbe usare:
https://www.b4x.com/android/forum/t...listview-with-imageviews-bitmap-files.101299/

Non so se esistano librerie per convertire immagini da jpeg a png (né so se nel tuo caso sarebbe necessario); non sapevo (forse non ho letto tutto il thread?) se usassi tuoi file immagine inseriti nel progetto (Assets). In questo caso avresti potuto usare un qualunque tool per convertirli, prima di aggiungerli al progetto.

Sarebbe possibile farlo fare anche all'app (la conversione jpeg -> png) se necessario , dato che esiste questa possibilità (mancherebbe la parte di lettura del file, questa parte è presa da un help contestuale);
B4X:
Dim Out As OutputStream
Out = File.OpenOutput(File.DirRootExternal, "Test.png", False)
Bitmap1.WriteToStream(out, 100, "PNG")
Out.Close
 

3394509365

Active Member
Licensed User
Longtime User
Scusate se mi inserisco a gamba tesa nella discuzzione, anche io avrei più o meno lo stesso problema.

Ditemi se magari devo aprire una nuova discussione.

L' utente si crea una propria cartella di foto di testi di canzoni che poi richiama nell' app. Io ho fatto tutto col jpg.
Naturalmente le foto che vengono caricate potrebbero essere enormi, e questo non voglio che succeda.

Questa è quello che succede:

La foto viene caricata in una ImageView:



B4X:
Sub ButtonGetImage_Click
    SongTitle=""
    Main.CC.Show("image/*", "Choose image")
    lblHelp.Color=Colors.Transparent
    lblHelp.Text="Choose a title!"
    
End Sub
Sub CC_Result (Success As Boolean, Dir As String, filename As String)
    
    If Success = True Then
        ImageView1.Bitmap = LoadBitmap(Dir,filename)
    Else
        ToastMessageShow("Error :(",True)
    End If
    



L' utente se la guarda e se gli piace la salva nella cartella che ho stabilito.

[CODE=b4x]
If File.Exists(FullPath, SongTitleFinito & ".jpg") = False Then

             
        Dim NomeSave As String = SongTitleFinito & ".jpg"
        
        Dim Data() As Byte
            
        ''''''''''''''''''''''''''''''''''''
        If (ImageView1.Bitmap) <> Null  Then
            Data = ImageToBytes(ImageView1.Bitmap)
        
    
    
        Try
                
                Dim out As OutputStream
                out = File.OpenOutput(FotoPath, NomeSave,False)
                out.WriteBytes(Data, 0, Data.Length)
                out.Close
            
                'svuoto LastException' immagine
                ImageView1.Bitmap = Null
                ImageView1.Visible=True  ' forse non serve
                
                ToastMessageShow( "SAVED" , True)
                
                lblHelp.Color=Colors.Green
            
                lblHelp.Text="Saved: " & CRLF & NomeSave
            
            'pulisco le variabili e svuoto la lista delle canzoni presenti prima
                SongTitle=""
                
                lblListaPresenti.Text=""
                
            Catch    
                
                MsgboxAsync("Error image","ATTENTION")
                      
                Return
        End Try
        
        Else
            MsgboxAsync("No image selected","ATTENTION")
                      
            Return
        
    End If
    
Else  ' chiedo se corretto?
        
        ToastMessageShow(SongTitleFinito & " " & "ATTENTION: NOT SAVED" , True)
        
        lblHelp.Color=Colors.red
        lblHelp.Text= SongTitleFinito & CRLF & "ATTENTION: already exists "
        'SongTitle=""
End If
    



public Sub ImageToBytes(Image As Bitmap) As Byte()
    Dim out As OutputStream
    out.InitializeToBytesArray(0)
    Image.WriteToStream(out, 100, "JPEG")
    out.Close
        
    Return  out.ToBytesArray
    
End Sub

A questo punto, però vorrei che le foto non superino una certa dimensione, sia per poterle caricare più velocemente e secondo per non occupare troppio spazio inutilmente
 

Sagenut

Expert
Licensed User
Longtime User
La dimensione occupata in memoria non è collegata alla dimensione in KB del file.
La stessa immagine salvata in 2 formati differenti, uno che occupa 1MB e uno che occupa 300KB ad esempio, occuperanno la stessa quantità di memoria una volta caricate.
La discriminante è la dimensione in pixels dell'immagine sorgente.
Come già scritto in questa discussione puoi usare
LoadBitmapResize per visualizzare l'immagine alla dimensione voluta a livello video, anche deformando l'immagine in larghezza o altezza se vuoi.
LoadBitmapSample per caricare una versione non a piena qualità dell'immagine che occupa meno spazio in memoria.
Se l'immagine a video non è molto grande forse anche la qualità non ne risentirà eccessivamente.
 

3394509365

Active Member
Licensed User
Longtime User
quindi per adattarlo a quello che mi serve

LoadBitmapResize per visualizzare l'immagine

ma poi persalvarla nella cartella che mi interessa devo usare questo

B4X:
 Dim out As OutputStream
                out = File.OpenOutput(FotoPath, NomeSave,False)
                out.WriteBytes(Data, 0, Data.Length)
                out.Close

e per rivisualizzarla questo ?


LoadBitmapSample

ho capito bene?

ma comunque io vorrei non permettere il salvataggio di foto che superino una determinata dimensnione per es max 2500*3500con al max 2000kb
 
Last edited:

Sagenut

Expert
Licensed User
Longtime User
Salvando una immagine dopo averla caricata con il Resize dovrebbe permetterti di salvarla alla nuova dimensione che vuoi.
Dopo puoi caricarla normalmente con un LoadBitmap o con un LoadBitmapResize se comunque hai bisogno di mostrarla ad una dimensione differente.
Esempio:
hai una immagine iniziale da 5000 x 5000.
La salvi ristretta a 1000 x 1000 per risparmiare spazio (caricandola con il LoadBitmapResize e poi salvaldola con OutputStream).
Comunque la vuoi visualizzare in un riquadro da 500 x 500 (caricandola di nuovo con LoadBitmapResize).
LoadBitmapSample è comodo per mostrare delle miniature usando meno memoria o comunque una anteprima senza caricare l'immagine nella sua forma completa.
Per altre info forse è meglio aprire una tua discussione al riguardo.
 

3394509365

Active Member
Licensed User
Longtime User
ok lo farò anche perchè "Salvando una immagine dopo averla caricata con il Resize dovrebbe permetterti di salvarla alla nuova dimensione che vuoi. " non lo fa
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
Non so esattamente come tu voglia fare, cioè quanti formati (intesi come risoluzione) ti servano, se due o tre.

Mettiamo che su file la risoluzione sia 2000x1000, potresti mostrarla in una ImageView caricandola con LoadBitmapResize, passando a questa istruzione le dimensioni della ImageView. Se poi vuoi salvarla con la risoluzione che ha questa ImageView, non devi fare altro che salvarla come fa la tua routine
B4X:
public Sub ImageToBytes(Image As Bitmap) As Byte()
    Dim out As OutputStream
    out.InitializeToBytesArray(0)
    Image.WriteToStream(out, 100, "PNG") ' <--- NOTA che ho cambiato questo; salvando in formato PNG il file sarà di "peso" minore.
    out.Close
      
    Return  out.ToBytesArray
  
End Sub

Se invece vuoi salvarla con risoluzione intermedia tra quella originale del file e quella della ImageView, crea una seconda ImageView, invisibile, delle dimensioni volute, e ripeti il procedimento (carica da file usando LoadBitmapResize in questa seconda ImageView e salva la bitmap di quest'ultima).

Nota che ci sarà sicuramene il problema del rapporto base/altezza diverso tra la tua (o le tue) ImageView e la risoluzione dell'immagine caricata.
Dovresti usare:
https://www.b4x.com/android/forum/threads/b4x-xui-fill-and-fit-images-without-distortion.86627/
 
Last edited:
Top