Estrarre il file thumbnail contenuto nel 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
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 Button1_Click() 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) With PictureBox1 .Image = Image.FromString(s) .Resize(.Image.W, .Image.H) End With End
Uso delle risorse del API di libzip
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