Differenze tra le versioni di "Estrarre il file thumbnail contenuto nel file odt"

Da Gambas-it.org - Wikipedia.
 
(4 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
Il file di formato ''ODT'', file di testo facente parte della famiglia dei file ''ODF'', è sostanzialmente un file ''XML'' contenuto in un file .zip . Infatti all'interno del file compresso ''ODT'' si trova - tra gli altri - anche la cartella ''Thumbnails/'', la quale a sua volta contiene un file immagine in formato ''.png'' di piccole dimensioni che riproduce quanto mostrato dal file ''odt''.
 
Il file di formato ''ODT'', file di testo facente parte della famiglia dei file ''ODF'', è sostanzialmente un file ''XML'' contenuto in un file .zip . Infatti all'interno del file compresso ''ODT'' si trova - tra gli altri - anche la cartella ''Thumbnails/'', la quale a sua volta contiene un file immagine in formato ''.png'' di piccole dimensioni che riproduce quanto mostrato dal file ''odt''.
 
  
 
==Uso delle sole risorse di Gambas==
 
==Uso delle sole risorse di Gambas==
Per estrarre il file ''thumbnail'' .png, contenuto nel file ''.odt'', senza dover preventivamente utilizzare un decompressore il file medesimo, si può adottare il seguente codice che utilizza esclusivamente risorse native di Gambas:
+
Per estrarre il file ''thumbnail'' .png, contenuto nel file ''.odt'', senza dover preventivamente decomprimere quest'ultimo, si può adottare il seguente codice che utilizza esclusivamente risorse native di Gambas:
  '''Public''' Sub Form_Open()
+
  Public Sub Form_Open()
 
    
 
    
   Dim fl As File
+
   Dim odt, s As String
   Dim i, sp As Integer
+
   Dim i, fi As Integer
   Dim bb As Byte[]
+
   Dim s As String
+
  odt = "<FONT Color=darkgreen>''/percorso/del/file.odt''</font>"
 +
 +
  s = File.Load(odt)
 +
  i = InStr(s, "Thumbnails/thumbnail")
 +
 +
<FONT Color=gray>' ''Individua con sicurezza i primi byte dell'immagine di formato "PNG":''</font>
 +
  i = InStr(s, "\x89PNG", i)
 +
 +
<FONT Color=gray>' ''Individua gli ultimi 4 byte del file "PNG":''</font>
 +
   fi = InStr(s, "\xAE\x42\x60\x82", i)
 +
 +
<FONT Color=gray>' ''Legge i soli dati appartenenti al file immagine ".png":''</font>
 +
   s = Mid(s, i, (fi - i) + 4)
 
    
 
    
  fl = Open "<FONT Color=gray>''/percorso/del/file.odt''</font>" For Read
 
   
 
<FONT Color=gray>' ''Legge la dimensione del file immagine ".png" presente nel file ".odt":''</font>
 
  Seek #fl, 99
 
  Read #fl, i
 
 
 
<FONT Color=gray>' ''Legge dopo quanti byte iniziano i dati del file immagine ".png":''</font>
 
  Read #fl, sp
 
 
 
<FONT Color=gray>' ''Ci si sposta sul primo byte dei dati del file immagine ".png":''</font>
 
  Seek #fl, Seek(fl) + sp
 
 
 
<FONT Color=gray>' ''Legge i soli dati appartenenti al file immagine ".png":''</font>
 
  With bb = New Byte[i]
 
    .Read(fl, 0, i)
 
<FONT Color=gray>' ''Salva i dati in una variabile di tipo "Stringa":''</font>
 
    s = .ToString(0, i)
 
  End With
 
 
 
  fl.Close
 
 
 
 
  <FONT Color=gray>' ''Salva i dati letti in un nuovo file immagine ".png" esternamente al file ".odt":''</font>
 
  <FONT Color=gray>' ''Salva i dati letti in un nuovo file immagine ".png" esternamente al file ".odt":''</font>
  File.Save("<FONT Color=gray>''/percorso/del/file.png''</font>", s)
+
  File.Save("/tmp/file.png", s)
 
+
 
  PictureBox1.Picture = Picture.Load("<FONT Color=gray>''/percorso/del/file.png''</font>")
+
  PictureBox1.Image = Image.FromString(s)
 
+
  '''End'''
+
  End
  
  
==Uso delle risorse del API di ''libzip.so.4.0.0''==
+
==Uso delle risorse del API di ''libzip.so.5.5''==
Volendo si possono utilizzare alcune risorse della libreria "''libzip.so.4.0.0''", la quale pertanto dovrà essere presente nel sistema ed essere richiamata nel progetto Gambas.
+
E' possibile utilizzare alcune risorse della libreria condivisa "''libzip.so.5.5'' ", che pertanto dovrà essere presente nel sistema ed essere richiamata nel progetto Gambas.
  
 
Mostriamo un esempio pratico:
 
Mostriamo un esempio pratico:
  Library "libzip:4.0.0"
+
  Library "libzip:5.5"
 
   
 
   
 
  Public Struct zip_stat
 
  Public Struct zip_stat
Riga 88: Riga 78:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
    
 
    
   Dim percorsoODT As String
+
   Dim odt As String
 
   Dim z, zf As Pointer
 
   Dim z, zf As Pointer
 
   Dim i, lun As Integer
 
   Dim i, lun As Integer
Riga 98: Riga 88:
 
   Dim buf As New Byte[64]
 
   Dim buf As New Byte[64]
 
    
 
    
  percorsoODT = "<FONT Color=gray>''/percorso/del/file.odt''</font>"
+
  odt = "<FONT Color=darkgreen>''/percorso/del/file.odt''</font>"
 
    
 
    
  z = zip_open(percorsoODT, 0, 0)
+
  z = zip_open(odt, 0, 0)
  If z = 0 Then
+
  If z == 0 Then
    zip_close(z)
+
    zip_close(z)
    Error.Raise("Impossibile aprire un file '.zip' !")
+
    Error.Raise("Impossibile aprire un file '.zip' !")
  Endif
+
  Endif
 
    
 
    
  For i = 0 To zip_get_num_entries(z, 0) - 1
+
  For i = 0 To zip_get_num_entries(z, 0) - 1
     
+
    If zip_stat_index(z, i, 0, zs) = 0 Then
    If zip_stat_index(z, i, 0, zs) = 0 Then
+
      zf = zip_fopen_index(z, i, 0)
      zf = zip_fopen_index(z, i, 0)
+
      If zf == 0 Then
      If zf = 0 Then
+
        zip_fclose(zf)
        zip_fclose(zf)
+
        Error.Raise("Errore alla funzione 'zip_fopen_index()' !")
        Error.Raise("Errore alla funzione 'zip_fopen_index()' !")
+
      Endif
      Endif
+
      If String@(zs.name) == "Thumbnails/thumbnail.png" Then
      If String@(zs.name) == "Thumbnails/thumbnail.png" Then
+
        fl = Open "/tmp/thumbnail.png" For Create
        fl = Open File.Dir(percorsoODT) &/ "thumbnail.png" For Create
+
        While l < zs.size
        While l < zs.size
+
          lun = zip_fread(zf, buf, 64)
          lun = zip_fread(zf, buf, 64)
+
          If lun < 0 Then Error.Raise("Errore nella lettura del file !")
          If lun < 0 Then Error.Raise("Errore nella lettura del file !")
+
          buf.Write(fl, 0, lun)
          buf.Write(fl, 0, lun)
+
          l += lun
          l += lun
+
        Wend
        Wend
+
        fl.Close
        fl.Close
+
      Endif
      Endif
+
      zip_fclose(zf)
      zip_fclose(zf)
+
    Endif
    Endif
+
  Next
         
 
  Next
 
 
 
  zip_close(z)
 
 
 
'''End'''
 
 
 
 
 
==Mostrare in una ''PictureBox'' l'immagine del ''thumbnail'' senza creare un file immagine d'appoggio==
 
Se si intende mostrare, per esempio, in una ''PictureBox'' l'immagine del ''thumbnail'' senza creare un file immagine d'appoggio (come avviene negli esempi precedenti), allora si potranno tulizzare alcune risorse del API di ''libgdk_pixbuf''.
 
 
 
Per poter fruire in Gambas di tali risorse, sarà necessario aver installato e richiamare la libreria dinamica condivisa: "''libgdk_pixbuf-2.0.so.0.3200.2''"
 
 
 
 
 
Mostriamo un esempio:
 
Library "libgdk_pixbuf-2.0:0.3200.2"
 
 
<FONT Color=gray>' ''GdkPixbufLoader * gdk_pixbuf_loader_new(void)''
 
' ''Creates a new pixbuf loader object.''</font>
 
Private Extern gdk_pixbuf_loader_new() As Pointer
 
 
<FONT Color=gray>' ''gboolean gdk_pixbuf_loader_write (GdkPixbufLoader *loader, const guchar *buf, gsize count, GError **error)''
 
' ''Causes a pixbuf loader to parse the next count bytes of an image.''</font>
 
Private Extern gdk_pixbuf_loader_write(loader As Pointer, buf As Pointer, count As Integer, Gerror As Pointer)
 
 
<FONT Color=gray>' ''gboolean gdk_pixbuf_loader_close (GdkPixbufLoader *loader, GError **error)''
 
' ''Informs a pixbuf loader that no further writes.''</font>
 
Private Extern gdk_pixbuf_loader_close(loader As Pointer, Gerror As Pointer)
 
 
<FONT Color=gray>' ''GdkPixbuf * gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader)''
 
' ''Queries the GdkPixbuf that a pixbuf loader is currently creating.''</font>
 
Private Extern gdk_pixbuf_loader_get_pixbuf(loader As Pointer) As Pointer
 
 
   
 
   
<FONT Color=gray>' ''int gdk_pixbuf_get_width (const GdkPixbuf *pixbuf)''
+
  zip_close(z)
' ''Queries the width of a pixbuf.''</font>
 
Private Extern gdk_pixbuf_get_width(pixbuf As Pointer) As Integer
 
 
   
 
   
  <FONT Color=gray>' ''int gdk_pixbuf_get_height (const GdkPixbuf *pixbuf)''
+
  End
' ''Queries the height of a pixbuf.''</font>
 
Private Extern gdk_pixbuf_get_height(pixbuf As Pointer) As Integer
 
 
<FONT Color=gray>' ''int gdk_pixbuf_get_n_channels (const GdkPixbuf *pixbuf)''
 
' ''Queries the number of channels of a pixbuf.''</font>
 
Private Extern gdk_pixbuf_get_n_channels(pixbuf As Pointer) As Integer
 
 
<FONT Color=gray>' ''gboolean gdk_pixbuf_get_has_alpha (const GdkPixbuf *pixbuf)''
 
' ''Queries whether a pixbuf has an alpha channel (opacity information).''</font>
 
Private Extern gdk_pixbuf_get_has_alpha(pixbuf As Pointer) As Boolean
 
 
<FONT Color=gray>' ''guchar * gdk_pixbuf_get_pixels (const GdkPixbuf *pixbuf)''
 
' ''Queries a pointer to the pixel data of a pixbuf.''</font>
 
Private Extern gdk_pixbuf_get_pixels(pixbuf As Pointer) As Pointer
 
 
 
'''Public''' Sub Form_Open()
 
 
 
  Dim lo, pb, dati As Pointer
 
  Dim fl As File
 
  Dim i, sp, w, h, c, bo, whc As Integer
 
  Dim bb, cc As Byte[]
 
  Dim st As Stream
 
  Dim immago As Image
 
 
 
  fl = Open "<FONT Color=gray>''/percorso/del/file.odt''</font>" For Read
 
   
 
  Seek #fl, 99
 
  Read #fl, i
 
   
 
  Read #fl, sp
 
  Seek #fl, Seek(fl) + sp
 
   
 
  With bb = New Byte[i]
 
    .Read(fl, 0, i)
 
  End With
 
   
 
  fl.Close
 
 
 
  lo = gdk_pixbuf_loader_new()
 
 
 
  gdk_pixbuf_loader_write(lo, bb.data, bb.count, 0)
 
 
 
  gdk_pixbuf_loader_close(lo, 0)
 
 
 
  pb = gdk_pixbuf_loader_get_pixbuf(lo)
 
 
 
  w = gdk_pixbuf_get_width(pb)
 
  Print "Larghezza:  "; w; " pixel"
 
  h = gdk_pixbuf_get_height(pb)
 
  Print "Altezza:    "; h; " pixel"
 
  c = gdk_pixbuf_get_n_channels(pb)
 
  Print "Canali:      "; c
 
  bo = gdk_pixbuf_get_has_alpha(pb)
 
  Print "Canale Alfa: "; CBool(bo)
 
 
 
  dati = gdk_pixbuf_get_pixels(pb)
 
 
 
  whc = w * h * c
 
 
 
<FONT Color=gray>' ''Dereferenziamo il "Puntatore" con i "Memory Stream", e ne leggiamo i valori contenuti (i dati/byte grezzi dei pixel) dell'immagine:''</font>
 
  st = Memory dati For Read
 
  With bb = New Byte[whc]
 
    .Read(st, 0, .Count)
 
  End With
 
  st.Close
 
 
 
  For i = w * c To whc - 1 Step w * c
 
    bb.Remove(i, 1)
 
  Next
 
 
 
  cc = New Byte[bb.Count]
 
  For i = 0 To cc.Count - 1 Step 3
 
    cc[i + 2] = bb[i]
 
    cc[i + 1] = bb[i + 1]
 
    cc[i] = bb[i + 2]
 
  Next
 
 
 
  For i = 3 To w * h * 4.023 Step 4
 
    cc.Add(&FF, i)
 
  Next
 
 
 
  With immago = New Image(w, h, 0, 0)
 
    st = Memory .Data For Write
 
  End With
 
  cc.Write(st, 0, cc.Count)
 
  st.Close
 
 
 
  With PictureBox1
 
    .X = 10
 
    .Y = 10
 
    .W = w
 
    .H = h
 
    .Picture = immago.Picture
 
  End With
 
 
 
'''End'''
 
 
 
  
  
Riga 271: Riga 129:
 
* http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2-part1.pdf
 
* http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2-part1.pdf
 
* http://opendocument.xml.org/
 
* http://opendocument.xml.org/
* https://developer.gnome.org/gdk-pixbuf/unstable/
 
* http://openbooks.sourceforge.net/books/wga/graphics-gdk-pixbuf.html
 

Versione attuale delle 10:26, 21 gen 2024

Il file di formato ODT, file di testo facente parte della famiglia dei file ODF, è sostanzialmente un file XML contenuto in un file .zip . Infatti all'interno del file compresso ODT si trova - tra gli altri - anche la cartella Thumbnails/, la quale a sua volta contiene un file immagine in formato .png di piccole dimensioni che riproduce quanto mostrato dal file odt.

Uso delle sole risorse di Gambas

Per estrarre il file thumbnail .png, contenuto nel file .odt, senza dover preventivamente decomprimere quest'ultimo, si può adottare il seguente codice che utilizza esclusivamente risorse native di Gambas:

Public Sub Form_Open()
 
 Dim odt, s As String
 Dim i, fi As Integer

 odt = "/percorso/del/file.odt"

 s = File.Load(odt)
 i = InStr(s, "Thumbnails/thumbnail")

' Individua con sicurezza i primi byte dell'immagine di formato "PNG":
 i = InStr(s, "\x89PNG", i)

' Individua gli ultimi 4 byte del file "PNG":
 fi = InStr(s, "\xAE\x42\x60\x82", i)

' Legge i soli dati appartenenti al file immagine ".png":
 s = Mid(s, i, (fi - i) + 4)
 
' Salva i dati letti in un nuovo file immagine ".png" esternamente al file ".odt":
 File.Save("/tmp/file.png", s)
 
 PictureBox1.Image = Image.FromString(s)

End


Uso delle risorse del API di libzip.so.5.5

E' possibile utilizzare alcune risorse della libreria condivisa "libzip.so.5.5 ", che pertanto dovrà essere presente nel sistema ed essere richiamata nel progetto Gambas.

Mostriamo un esempio pratico:

Library "libzip:5.5"

Public Struct zip_stat
  valid As Long
  name As Pointer
  index As Long
  size As Long
  comp_size As Long
  mtime As Long
  crc As Integer
  comp_method As Short
  encryption_method As Short
  flags As Integer
End Struct

' struct zip *zip_open(const char *, int, int *)
' Open zip archive.
Private Extern zip_open(path As String, flags As Integer, errorp As Pointer) As Pointer

' zip_int64_t zip_get_num_entries(zip_t *, zip_flags_t)
' Get number of files in archive.
Private Extern zip_get_num_entries(archive As Pointer, flags As Integer) As Long

' int zip_stat_index(struct zip *, int, int, struct zip_stat *)
' Get information about file by index.
Private Extern zip_stat_index(archive As Pointer, index As Integer, flags As Integer, sb As Zip_stat) As Integer

' struct zip_file * zip_fopen_index(struct zip *, int, int)
' Open file in zip archive for reading by index
Private Extern zip_fopen_index(archive As Pointer, index As Integer, flags As Integer) As Pointer

' zip_int64_t zip_fread(struct zip_file *, void *, zip_uint64_t)
' Read from file.
Private Extern zip_fread(zfile As Pointer, buf As Byte[], nbytes As Long) As Long

' int zip_fclose(struct zip_file *)
' Close file in zip archive.
Private Extern zip_fclose(zfile As Pointer) As Integer

' int zip_close(struct zip *)
' Close zip archive.
Private Extern zip_close(archive As Pointer) As Integer


Public Sub Main()
 
 Dim odt As String
 Dim z, zf As Pointer
 Dim i, lun As Integer
 Dim zs As New Zip_stat
 Dim l As Long
 Dim fl As File
 Dim buf As New Byte[64]
 
 odt = "/percorso/del/file.odt"
  
 z = zip_open(odt, 0, 0)
 If z == 0 Then
   zip_close(z)
   Error.Raise("Impossibile aprire un file '.zip' !")
 Endif
  
 For i = 0 To zip_get_num_entries(z, 0) - 1
   If zip_stat_index(z, i, 0, zs) = 0 Then
     zf = zip_fopen_index(z, i, 0)
     If zf == 0 Then
       zip_fclose(zf)
       Error.Raise("Errore alla funzione 'zip_fopen_index()' !")
     Endif
     If String@(zs.name) == "Thumbnails/thumbnail.png" Then
       fl = Open "/tmp/thumbnail.png" For Create
       While l < zs.size
         lun = zip_fread(zf, buf, 64)
         If lun < 0 Then Error.Raise("Errore nella lettura del file !")
         buf.Write(fl, 0, lun)
         l += lun
       Wend
       fl.Close
     Endif
     zip_fclose(zf)
   Endif
 Next

 zip_close(z)

End


Riferimenti