' Rapid-Q by William Yu (c)1999-2000 . ' ================================================================================ ' Upload_il_tuo_script_su_Rapidq.it ' Gestione_di_file_di_dati_binari Un file di dati binari è più carino di un file di testo o di un file di record. Il file può avere qualsiasi tipo di ordine e contenere qualsiasi tipo di dato. Quindi nel tentativo di rendere questo articolo più pratico parleremo di un particolare tipo di file binario e scriveremo un piccolo programma per leggerlo. Layout di un file PCXPCX è uno dei diversi formati grafici usati per immagazzinare le immagini in un file di computer. Uno dei formati PCX conserva una singola immagine fatta di pixels che sono uno dei 256 differenti valori dei colori usati. Questo semplice formato è il file oggetto della nostra trattazione riguardo all'accesso di un file di dati binario. Il layout di base di un file PCX è il seguente: [HEADER/INTESTAZIONE][DATI DELL'IMMAGINE][PALETTE DEI COLORI] L'intestazione di un file PCX è di 128 bytes di informazioni che descrivono l'immagine contenuta nella sezione DATI DELL'IMMAGINE.L'intestazione è suddivisa nei seguenti tipi di informazioni: 1 BYTE per ID del produttore 1 BYTE per il numero della versione 1 BYTE per il tipo di codificatore 1 BYTE per i bits usati per ciascun pixel 1 SHORT INTEGER per l'estremo sinistro dell'immagine 1 SHORT INTEGER per l'estremo superiore dell'immagine 1 SHORT INTEGER per l'estremo destro dell'immagine 1 SHORT INTEGER per l'estremo inferiore dell'immagine 1 SHORT INTEGER per la risoluzione orizzontale 1 SHORT INTEGER per la risoluzione verticale 48 BYTES per la mappa colori usata in immagini di 16 colori 1 BYTE riservato per uso futuro 1 BYTE usato per il numero di bit_planes (piani ) presenti nell'immagine 1 SHORT INTEGER per il numero totale di bytes per ine 1 SHORT INTEGER per il tipo di palette usata 1 SHORT INTEGER per le dimensioni totali orizzontali dello schermo su cui porre l'immagine 1 SHORT INTEGER per le dimensioni totali verticali dello schermo su cui porre l'immagine 54 BYTES riservati per uso futuro Possiamo tradurre la suesposta intestazione del file (HEADER) in una struttura UDT che faciliti la gestione della lettura del file, ad esempio: TYPE PcxHeaderType Manufacturer AS BYTE Version AS BYTE Encoding AS BYTE BitsPerPixel AS BYTE xmin AS SHORT ymin AS SHORT xmax AS SHORT ymax AS SHORT Hres AS SHORT Vres AS SHORT ColorMap AS STRING * 48 Reserved1 AS BYTE NumPlanes AS BYTE BytesPerLine AS SHORT PaletteType AS SHORT HScrSize AS SHORT VScrSize AS SHORT Reserved2 AS STRING * 54 END TYPE DIM PcxHeader AS PcxHeaderType In questo modo possiamo aprire un file PCX ed estrarre l'intera intestazione come una unica informazione: DIM PcxFile AS QFileStream PcxFile.Open( "filename.pcx", fmOpenRead ) PcxFile.ReadUDT( PcxHeader ) Rende più facile anche localizzare le informazioni specifiche relative all'immagine: DIM PcxImage AS QBitMap PcxImage.Width = PcxHeader.xmax - PcxHeader.xmin + 1 PcxImage.Height = PcxHeader.ymax - PcxHeader.Ymin + 1 La palette dei colori, per il nostro scopo, è di 768 byte di informazioni, conservate alla fine del file PCX. PcxFile.Seek( -768, soFromEnd ) La palette dei colori è suddivisa in 3 segmenti di 256 colori di 3 BYTES ciascuno ( 256 * 3 = 768 ). Ciascun segmento di colore conserva i seguenti dati: 1 BYTE per l'intensità del coloreRosso 1 BYTE per l'intensità del colore Verde 1 BYTE per l'intensità del coloreBlu DIM PcxRed AS BYTE DIM PcxGreen AS BYTE DIM PcxBlue AS BYTE Possiamo creare un loop di 256 ripetizioni e leggere i 3 valori dei colori di base insieme, e convertirli nel corrispondente valore di colore per Rapid-Q. DIM PcxColors( 0 TO 255 ) AS INTEGER FOR Counter = 0 TO 255 PcxFile.Read( PcxRed ) PcxFile.Read( PcxGreen ) PcxFile.Read( PcxBlue ) PcxColors( Counter ) = ( PcxBlue SHL 16 ) + _ ( PcxGreen SHL 8 ) + _ ( PcxRed ) NEXT Counter I colori di Rapid-Q sono tenuti in una variabile INTEGER nell'ordine Blue/Verde/ Rosso. La nostra linea di conversione usa il comando SHL ( shift left = slitta a sinistra) per spostare il BYTE del valore del colore nella sua posizione corrispondente nella variabile INTEGER. valore decimale= 5 valore bit = 00000101 5 SHL 8 = 0000010100000000 5 SHL 16 = 000001010000000000000000 messi insieme= 000001010000010100000101 Qui sopra è stato mostrato come funzionaa conversione di 3 valori BYTE, necessaria per ricavare il valore INTEGER. I DATI DELL'IMMAGINE sono la informazione rimasta dalla fine dell'intestazione ( byte 129 ) all'inizio della palette colore( 769 bytes dalla fine del file). PcxFile.Seek( SizeOf( PcxHeader ), soFromBeginning ) DIM PcxByte AS BYTE FOR Counter = SizeOf( PcxHeader ) TO ( PcxFile.Size - 768 ) PcxFile.Read( PcxByte ) ' decode RLE here NEXT Counter Run Length Encoding ( RLE ) I DATI DELL'IMMAGINE del file PCX non sono tenuti in un rapporto lineare valore-pixel, ma sono conservati mediante un tipo di compressione nota come Run Length Encoding ( RLE ). RLE è fondamentalmente una coppia di elementi di dati che dicono quante volte il valore è immagazzinato e il valore attuale. La RLE del file PCX segue queste regole specifiche: * Se il valore del BYTE è <= 192, esso è un colore. Il valore del colore è l'indice di un gruppo di RGB della palette colore. Un singolo pixel del colore va all'immagine. * Se il valore del BYTE è > di 192, esso è un valore run. Sottraendo 192 dal valore run otterremo il conteggio attuale. Legge il prossimo BYTE come valore colore. IF PcxByte <= 192 THEN PcxRun= 1 ' color already in PcxByte ELSE PcxRun= PcxByte - 192 PcxFile.Read( PcxByte ) END IF Noi poi poniamo il valore del colore sull'immagine il numero di volte del valore run. DIM RunCounter AS INTEGER DIM currentPCXline AS INTEGER DIM currentPCXcol AS INTEGER FOR RunCounter = 1 TO PcxRun ' advance to next column of pixels currentPCXcol = currentPCXcol + 1 ' set the QBitMap pixel to the color value PcxImage.Pixel( currentPCXcol, currentPCXline ) = _ PcxColors( PcxByte ) ' check if run continues off edge of QBitMap IF currentPCXcol >= PcxImage.Width THEN ' advance to next row of pixels currentPCXline = currentPCXline + 1 ' reset pixel column to zero currentPCXcol = 0 END IF NEXT RunCounter Il problema ovvio della regola suesposta cade quando un singolo pixel deve essere immagazzinato con un valore di colore superiore a 192. Per evitare tale limitazione di un valore run = 1 il valore del colore viene codificato. Ad esempio : un singolo pixel del valore colore 249 determina come codice RLE 193, 249. Run Length Encoding è un modo leggermente più semplice ed efficiente di immagazzinare immagini disegnate o immagini che contengono larghe sezioni dello stesso colore. Il principale problema per questo tipo di compressione della immagine è che non può essere usato per comprimere immagini che contenogono variazioni di colore estreme o altamente dettagliate. se l'immagine cambia colore ad ogni pixel, il PCX potrebbe essere di dimensioni doppie rispetto al file immagine originale. ' =============================================================================== ' 2003 Holyguard.net - 2007_Abruzzoweb