in una mia applicazione, visualizzo delle immagini scaricate da internet con questo codice:
Download
'immagine
.....
IMG = New HttpClient As "IMG"
IMG.url = Trim(Rssitems.getLink())
IMG.get(Null, User.Home & "/rssimage")
....
Visualizzazione
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 .....
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:
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