Autore Topic: Scaricare un file da internet IN MEMORIA  (Letto 504 volte)

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Scaricare un file da internet IN MEMORIA
« il: 05 Aprile 2016, 13:43:45 »
in una mia applicazione, visualizzo delle immagini scaricate da internet con questo codice:

Download
Codice: [Seleziona]
  'immagine
   .....
  IMG = New HttpClient As "IMG"
  IMG.url = Trim(Rssitems.getLink())
  IMG.get(Null, User.Home & "/rssimage")
  ....

Visualizzazione
Codice: [Seleziona]
Public Sub IMG_Finished()
  'Dim buffer As String
 
  'If Lof(IMG) Then Read #IMG, buffer, Lof(IMG)
 
  PictureBox_Immagine.Picture = Picture.Load(User.Home & "/rssimage")
 
End

ma dovendo girare su raspberry pi, vorrei limitare le scritture su SD e vorrei scaricare il file direttamente in ram.

Del resto "buffer" ha in memoria il binario dell'immagine ... non dovrebbe essere troppo esoterico caricarlo nel picture box .....
se corri, morirai stanco (motto degli sniper)

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 959
    • Mostra profilo
Re:Scaricare un file da internet IN MEMORIA
« Risposta #1 il: 05 Aprile 2016, 15:29:39 »
La prima cosa che mi viene in mente è spostare i dati da buffer alla PictureBox tramite Memory Stream, ma bisogna vedere se poi vengono letti correttamente.
Potresti partire da questo mio progettino:
http://www.gambas-it.org/smf/index.php?topic=3776.msg34696#msg34696
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Scaricare un file da internet IN MEMORIA
« Risposta #2 il: 05 Aprile 2016, 16:06:47 »
La prima cosa che mi viene in mente è spostare i dati da buffer alla PictureBox tramite Memory Stream...
Questo ragazzo farà molta strada nella programmazione in Gambas !   
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 959
    • Mostra profilo
Re:Scaricare un file da internet IN MEMORIA
« Risposta #3 il: 05 Aprile 2016, 16:26:49 »
Ho sentore di un che di sarcastico in codesta affermazione. Ho visto giusto oppure ho visto male? ;D
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re:Scaricare un file da internet IN MEMORIA
« Risposta #4 il: 05 Aprile 2016, 16:30:45 »

Questo ragazzo farà molta strada nella programmazione in Gambas !   

... e un futuro luminoso come autore di testi scientifici?  ;D  :D

Ciao Top Fuel ora ti lamenti anche quando si complimentano con te? Ehhh la vecchiaia....

 :D :D  :ciao: :ciao:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 959
    • Mostra profilo
Re:Scaricare un file da internet IN MEMORIA
« Risposta #5 il: 05 Aprile 2016, 18:14:00 »
Eccone un altro... :P :P :P
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Scaricare un file da internet IN MEMORIA
« Risposta #6 il: 05 Aprile 2016, 18:19:53 »
Ho visto giusto oppure ho visto male?
In via generale, possiamo dire che l'uso dei Memory Stream è per palati fini, poiché gli Stream sono una delle due risorse fornite da Gambas per leggere direttamente all'interno di un'area di memoria riservata puntata da una variabile di tpo ''Puntatore'', ed è l'unica risorsa di Gambas per scrivere direttamente all'interno di quell'area.

Detto questo, però, bisogna notare che la Classe HttpClient consente di scaricare in dati formato Stringa il file immagine "così com'è". Vengono, cioè scaricati i dati del file immagine nel suo formato in quanto tale, e non già i suoi dati immagine grezzi. Ciò significa che se viene scaricato un file immagine compresso non potremo fare altro che salvarlo dapprima in memoria dura e solo successivamente caricarlo in memoria RAM con le apposite risorse della Classe Image o della Classe Picture.
Va da sé che, se così stanno le cose, i raffinatissimi Memory Stream possono aiutarci ben poco.   

Ricapitolando: l'unica cosa, che abbiamo nella RAM immediatamente dopo lo scarico, è una variabile di tipo Stringa contenente tutti i dati del file immagine.  Questa è la parte difficile: come assegnare ad una PictureBox - pur facendo 1000 magheggi - i dati del file immagine "così com'è" contenuti dalla variabile di tipo Stringa senza passare preliminarmente per il metodo .Load() della Classe Image o della Classe Picture:-X
« Ultima modifica: 05 Aprile 2016, 18:25:01 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Re:Scaricare un file da internet IN MEMORIA
« Risposta #7 il: 06 Aprile 2016, 14:06:30 »
alla piu' brutta posso appoggiarmi ad un "ram disk" mappato nell'fstab del raspberry.

nell'fstab:

tmpfs   /tmp         tmpfs   nodev,nosuid,size=2G          0  0
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Scaricare un file da internet IN MEMORIA
« Risposta #8 il: 06 Aprile 2016, 19:04:19 »
Questa è la parte difficile: come assegnare ad una PictureBox i dati del file immagine "così com'è" contenuti dalla variabile di tipo Stringa senza passare preliminarmente per il metodo .Load() della Classe Image o della Classe Picture ?

Dunque, quanto chiesto da allegfede si può fare, risolvendo così anche il problema sopra posto da me, purché l'immagine da scaricare abbia il canale Alfa e dunque sia di formato a 32-bit - RGBA .
Bisognerà, però, utilizzare alcune funzioni esterne di gdk_pixbuf, nonché i Memory Stream sapientemente evocati prima da Top Fuel.

Mostro di seguito il codice con l'indirizzo web di un'immagine png da scaricare:
Codice: [Seleziona]
Private myhttp As New HttpClient As "myhttp"  


Library "libgtk-3:0.1000.8"

' GdkPixbufLoader * gdk_pixbuf_loader_new(void)'
' Creates a new pixbuf loader object.'
Private Extern gdk_pixbuf_loader_new() As Pointer

' gboolean gdk_pixbuf_loader_write (GdkPixbufLoader *loader, const guchar *buf, gsize count, GError **error)'
' Cause a pixbuf loader to parse the next count bytes of an image.'
Private Extern gdk_pixbuf_loader_write(lo As Pointer, buf As Pointer, i As Integer, po As Pointer)

' gboolean gdk_pixbuf_loader_close (GdkPixbufLoader *loader, GError **error)'
' Informs a pixbuf loader that no further writes.'
Private Extern gdk_pixbuf_loader_close(lo As Pointer, po As Pointer)

' GdkPixbuf * gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader)'
' Queries the GdkPixbuf that a pixbuf loader is currently creating.'
Private Extern gdk_pixbuf_loader_get_pixbuf(lo As Pointer) As Pointer
 
' guchar * gdk_pixbuf_get_pixels (const GdkPixbuf *pixbuf)'
' Queries a pointer to the pixel data of a pixbuf.'
Private Extern gdk_pixbuf_get_pixels(GdkPixbuf As Pointer) As Pointer

' int gdk_pixbuf_get_width (const GdkPixbuf *pixbuf)'
' Queries the width of a pixbuf.'
Private Extern gdk_pixbuf_get_width(GdkPixbuf As Pointer) As Integer

' int gdk_pixbuf_get_height (const GdkPixbuf *pixbuf)'
' Queries the height of a pixbuf.'
Private Extern gdk_pixbuf_get_height(GdkPixbuf As Pointer) As Integer

' int gdk_pixbuf_get_n_channels (const GdkPixbuf *pixbuf)'
' Queries the number of channels of a pixbuf.'
Private Extern gdk_pixbuf_get_n_channels(GdkPixbuf As Pointer) As Integer

' gboolean gdk_pixbuf_get_has_alpha (const GdkPixbuf *pixbuf)'
' Queries whether a pixbuf has an alpha channel (opacity information).'
Private Extern gdk_pixbuf_get_has_alpha(GdkPixbuf As Pointer) As Boolean


Public Sub Button1_Click()

' Invia la richiesta al server per scaricare il file immagine:'
   myhttp.URL = "http://f.tqn.com/y/painting/1/W/4/k/2/RGB_color_wheel_36.jpg.png"
   myhttp.Timeout = 15

' Lasciando il secondo parametro vuoto, i dati dell'immagine vengono salvati soltanto in memoria:
   myhttp.Get()
     
End


Public Sub MyHTTP_Finished()

  Dim s As String

   MyHTTP.Close
 
' Trasferiamo in una variabile stringa i dati dell'immagine scaricata e salvata in memoria:
   s = myhttp.Peek()
   Print "Immagine scaricata !\n\nDimensione: "; Len(s); " byte"
 
   Immagine(s)

End


Private Procedure Immagine(im As String)
 
 Dim bb, bb2 As Byte[]
 Dim w, h As Integer
 Dim loader, Pixbuf, dati As Pointer
 Dim c As Byte
 Dim bo As Boolean
 Dim st As Stream
 Dim immago As Image
   
   bb = Byte[].FromString(im)
 
   loader = gdk_pixbuf_loader_new()
 
   gdk_pixbuf_loader_write(loader, bb.data, bb.count, 0)
 
   gdk_pixbuf_loader_close(loader, 0)
 
   pixbuf = gdk_pixbuf_loader_get_pixbuf(loader)
 
   w = gdk_pixbuf_get_width(Pixbuf)
   Print "Larghezza: "; w; " pixel"
   h = gdk_pixbuf_get_height(Pixbuf)
   Print "Altezza:   "; h; " pixel"
   c = gdk_pixbuf_get_n_channels(Pixbuf)
   Print "Canali:    "; c

' Verifichiamo che l'immagine scaricata abbia il canale Alfa:
   bo = gdk_pixbuf_get_has_alpha(Pixbuf)
   If bo = False Then Error.Raise("L'immagine scaricata è priva del canale Alfa !")

   dati = gdk_pixbuf_get_pixels(Pixbuf)
   If IsNull(dati) Then Error.Raise("Impossibile ottenere un 'Puntatore' ai dati dei pixel dell'immagine !")

' Carichiamo i dati nel vettore "bb[]" per gestire successivamente i dati grezzi dei pixel:'
   st = Memory dati For Read
 
   With bb = New Byte[w * h * c]
     .Read(st, 0, .count)
   End With
 
' Effettua la correzione della disposizione dei dati RGB dei pixel dell'immagine scaricata:
   bb2 = Corregge(bb)
   
   st.Close
 
' Viene preparata la variabile di tipo Image per la gestione dei dati del futuro nuovo file immagine:'
   With immago = New Image(w, h, 0, 0)
     st = Memory .Data For Write
   End With
 
' Scrive i dati presenti nel vettore "bb[]" nell'area di memoria puntata dal Puntatore ".Data" della variabile di tipo "Image":
   bb2.Write(st, 0, bb2.Count)
 
   st.Close
 
   With PictureBox1
     .W = w
     .H = h
     .Picture = immago.Picture
   End With
 
End


Private Function Corregge(vett As Byte[]) As Byte[]
 
  Dim i As Integer
  Dim bb As Byte[]
 
   bb = New Byte[vett.Count]

   For i = 0 To vett.Max Step 4
     bb[i + 1] = vett[i + 1]
     bb[i + 2] = vett[i]
     bb[i] = vett[i + 2]
     bb[i + 3] = vett[i + 3]
   Next

   Return bb
 
End


Public Sub Button2_Click()

   Me.Close

End
« Ultima modifica: 06 Aprile 2016, 23:56:58 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »