Domanda

Sto facendo un po 'di lavoro in cui sto scaricando a livello di programmazione icone da siti specificati in un documento OpenSearch e devo estrarre la prima immagine (per ora) se è in formato ICO. Sono in grado di leggere l'intestazione del file ICO senza problemi e tagliare il primo file di immagine. Tuttavia, dopo aver letto il Voce di Wikipedia che spiega il formato del file Ho scoperto che, se l'immagine è in formato bitmap, il file è incompleto (manca l'intestazione). Quindi devo ricostruire questa intestazione prima di poter salvare i dati in un file, ma ho un po 'di difficoltà.

Secondo il Voce di Wikipedia per il formato di file BMP, l'intestazione è lunga 14 byte e dovrebbe contenere quanto segue:

Dati offset
0x0000    "BM", for our intents and purposes
0x0002    Size of the bitmap file in bytes
0x0006    Dependant on the application creating the file
0x0008    Dependant on the application creating the file
0x000A    Offset of the image data/pixel array

Ho pensato che la dimensione del file bitmap in byte avrebbe avuto la dimensione dell'immagine estratta + i 14 byte per l'intestazione, ma non sono sicuro di cosa scrivere a 0x0006, 0x0008 e come ottenere la posizione dell'array pixel Scrivi a 0x000A.

Ho letto l'articolo alcune volte, ma devo ammettere che la mia testa mi fa male. Questa è la mia prima esperienza nel fare questo genere di cose. Qualcuno può aiutarmi a capire come ottenere la posizione dell'array pixel?

È stato utile?

Soluzione

0x0006 e 0x0008 sono riservati, dovresti semplicemente mettere zeri lì. Per 0x000A, questa è la posizione in cui iniziano i dati dell'immagine effettiva nel file. Normalmente, l'intestazione che hai qui è seguita dall'intestazione DIB (a partire dall'offset 0x000E) e i primi quattro byte dell'intestazione DIB sono le sue dimensioni. Quindi prendi le dimensioni dell'intestazione di DIB, aggiungi il suo offset iniziale (0x000E) e quello che hai è la posizione in cui iniziano i dati effettivi: mettilo in posizione 0x000A.

Ecco i dati di esempio di un file BitMap casuale:

42 4D             "BM"
2E 78 08 00       Size of the entire bitmap file (0x8782E meaning 555054 bytes)
00 00             creator1, reserved
00 00             creator2, reserved
36 00 00 00       Image data starts at offset 0x36 because the next 0x28 bytes are DIB header
28 00 00 00       DIB header started and its size is 0x28 (40 bytes)
another 36 bytes
FF FF FF          First pixel of the image (white as it happens)

Se prendi il Favicon su serverfault.com Ad esempio, prenderesti la parte del file tra offset 0x0016 e 0x013E e prevedilo con con 42 4D 36 01 00 00 00 00 00 00 36 00 00 00. Il che ti dà una sorta di file bitmap corretto - e Irfanview lo visualizzerà persino. Tuttavia, i dati archiviati in file ICO e file BMP non sono esattamente gli stessi perché i file ICO devono archiviare informazioni di trasparenza. Questo è il motivo per cui questo Favicon ha dimensioni 16x32 secondo la sua intestazione DIB piuttosto che il 16x16 previsto.

Da Wikipedia:

Le immagini con meno di 32 bit di profondità del colore seguono un formato particolare: l'immagine è codificata come una singola immagine costituita da una maschera a colori (la "maschera XOR") insieme a una maschera di opacità (la "e maschera"). La maschera XOR deve precedere e mascherare i dati BitMap; Se l'immagine viene memorizzata in ordine bottom-up (che molto probabilmente è), la maschera XOR verrebbe disegnata sotto la maschera e la maschera.

Nel nostro caso particolare ciò significa che da 256 byte di dati sull'immagine i primi 64 byte sono la maschera XOR, gli ultimi 64 byte e la maschera e solo la parte centrale è la nostra immagine. Nel nostro caso particolare è possibile modificare i dati dell'immagine (offset 0x000A) a 0x76 per saltare la maschera XOR. Quindi cambieresti anche l'altezza dell'immagine nell'intestazione di DIB (offset 0x0016) a 0x10 per assicurarsi che la maschera sia ignorata. Qui queste manipolazioni ti daranno una bitmap valida, praticamente come quello che ti aspettavi. In generale, potrebbe essere meglio considerare le maschere, tuttavia piuttosto che ignorarle.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top