Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - modificare file BMP
Forum - C# / VB.NET - modificare file BMP - Pagina 3

Pagine: [ 1 2 3 4 5 ] Precedente | Prossimo
Avatar
Carlo (Member)
Guru


Messaggi: 1284
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 19:33
Domenica, 19/09/2021
PieroTofy, non ti permette di allegare uno zip da più di 2MB, se il tuo zip eccede di molto usa https://wetransfer.com/ e posta il link


in programmazione tutto è permesso
PM Quote
Avatar
bernie (Normal User)
Pro


Messaggi: 164
Iscritto: 23/10/2019

Segnala al moderatore
Postato alle 21:07
Domenica, 19/09/2021

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1284
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 22:57
Domenica, 19/09/2021
Ricevuti e analizzati, hanno le palette diverse.

Approcio: caricare il file d'origine, eseguire la trasformazione, salvare in bmp8bpp, copiare tutto l'Header del file d'origine nel file trasformato, aggiornare direttamente nel file la nuova dimensione del file, e le nuove dimensioni di Altezza e Larghezza dell'immagine.

L'Header nel file BMP, va dall'indirizzo 0x00 all'indirizzo 0x435 compreso

all'indirizzo 0x2 ci va la lunghezza del file 4bytes Little Endian
all'indirizzo 0x12 ci va la larghezza dell'immagine 4bytes Little Endian
all'indirizzo 0x16 ci va l'altezza dell'immagine 4bytes Little Endian

In questo modo se il file d'origine funziona anche il file d'uscita dovrebbe funzionare.

Lunedi e martedi, sono fuori intanto puoi vedere questo:

Codice sorgente - presumibilmente VB.NET

  1. Imports System.IO
  2.  
  3. Public Class Form1
  4.  
  5.     Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  6.         Dim NomeFileOriginale As String = "bandind2.bmp"
  7.         Dim NomeFileStirato As String = "zoombandind2.bmp"
  8.         Dim Originale As New Bitmap(NomeFileOriginale)
  9.         Dim paletteOriginale As Imaging.ColorPalette = Originale.Palette
  10.         Dim f As Integer = Originale.Palette.Flags '2=scalagrigio
  11.         Dim areaOriginale As New Rectangle(0, 0, Originale.Width, Originale.Height)
  12.         Dim bmpDataOriginale As Imaging.BitmapData = Originale.LockBits(areaOriginale, Imaging.ImageLockMode.ReadWrite, Originale.PixelFormat)
  13.         Dim ptrOriginale As IntPtr = bmpDataOriginale.Scan0 ' conterrà l'indirizzo di memoria
  14.         Dim bytesOriginale As Integer = Math.Abs(bmpDataOriginale.Stride) * Originale.Height
  15.         Dim levelValuesOriginale(bytesOriginale - 1) As Byte
  16.         System.Runtime.InteropServices.Marshal.Copy(ptrOriginale, levelValuesOriginale, 0, bytesOriginale)
  17.  
  18.         Dim ZoomH As Single = 5 ' solo interi, per i decimali bisogna pensarci un po'
  19.         Dim ZoomW As Single = 1 ' solo interi, per i decimali bisogna pensarci un po'
  20.  
  21.         Dim Stirata As New Bitmap(Originale.Width * ZoomW, Originale.Height * ZoomH, Imaging.PixelFormat.Format8bppIndexed)
  22.         Stirata.Palette = Originale.Palette
  23.  
  24.         Dim areaStirata As New Rectangle(0, 0, Stirata.Width, Stirata.Height)
  25.         Dim bmpDataStirata As Imaging.BitmapData = Stirata.LockBits(areaStirata, Imaging.ImageLockMode.ReadWrite, Stirata.PixelFormat)
  26.         Dim ptrStirata As IntPtr = bmpDataStirata.Scan0 ' conterrà l'indirizzo di memoria
  27.         Dim bytesStirata As Integer = Math.Abs(bmpDataStirata.Stride) * Stirata.Height
  28.         Dim levelValuesStirata(bytesStirata - 1) As Byte
  29.  
  30.         ' lettura e scrittura con zoom impostato
  31.         For rig = 0 To Originale.Height - 1
  32.             Dim limite As UInt32 = rig * bmpDataOriginale.Stride
  33.             Dim rig2 As Single = rig * ZoomH
  34.             For col = 0 To Originale.Width - 1
  35.                 Dim indOriginale = col + limite
  36.                 Dim livello As Byte = levelValuesOriginale(indOriginale)
  37.                 Dim col2 As Single = col * ZoomW
  38.                 For H = 0 To ZoomH - 1
  39.                     For W = 0 To ZoomW - 1
  40.                         Dim indStirata As UInt32 = col2 + W + (rig2 + H) * bmpDataStirata.Stride ' calcolo l'indice
  41.                         levelValuesStirata(indStirata) = livello
  42.                     Next
  43.                 Next
  44.             Next
  45.         Next
  46.  
  47.         System.Runtime.InteropServices.Marshal.Copy(levelValuesStirata, 0, ptrStirata, bytesStirata)
  48.         Stirata.UnlockBits(bmpDataStirata) 'sblocco bit
  49.         Stirata.Save(NomeFileStirato, Imaging.ImageFormat.Bmp)
  50.  
  51.         ' copio tutto l'Header del file d'origine nel file stirato
  52.         Dim fsO As New FileStream(NomeFileOriginale, FileMode.Open, FileAccess.Read)
  53.         Dim fsS As New FileStream(NomeFileStirato, FileMode.Open, FileAccess.Write)
  54.         Dim br As New BinaryReader(fsO)
  55.         Dim bw As New BinaryWriter(fsS)
  56.         Dim Byteletto As Byte ' lettura Byte
  57.         ' copio pari pari l'header d'origine
  58.         Do While fsO.Position <= &H435 '  fino alla fine dell'Header di un BMP 8bpp
  59.             Byteletto = br.ReadByte() ' lettura byte dall'origine
  60.             bw.Seek(CInt(fsO.Position - 1), SeekOrigin.Begin) ' posizione di destinazione
  61.             bw.Write(Byteletto) ' scrittura del byte letto in pari posizione
  62.         Loop
  63.  
  64.         ' aggiusto i parametri che potrebbero essere variati
  65.         bw.Seek(&H2, SeekOrigin.Begin) ' in posizione &H2 = lunghezza file
  66.         bw.Write(fsS.Length) ' metto la lunghezza del file
  67.         bw.Seek(&H12, SeekOrigin.Begin) ' in posizione &H12 = larghezza
  68.         bw.Write(Stirata.Width) ' scrivo la larghezza
  69.         bw.Seek(&H16, SeekOrigin.Begin) ' in posizione &H16 = altezza
  70.         bw.Write(Stirata.Height) ' scrivo l'altezza
  71.         fsO.Close()
  72.         fsS.Close()
  73.     End Sub
  74. End Class



Questo approcio fallirà con le grafiche che hai creato con .Net. :nono:
Per la creazione di una nuova immagine bisogna scegliere un Header, per esempio quello di (bandind2.bmp) copiarlo in una matrice di byte ed usarlo per la sostituzione.
Se invece si vuole essere più versatili, lo puoi fare anche da solo, puoi scegliere un'immagine a piacere per leggere l'Header da copiare, inserendo il nome del file scelto a riga 52 al posto della varabile NomeFileOriginale.
Devi tenere presente che sull'Header c'è anche la palette, non puoi mescolare l'Header di bandind2.bmp con palette a 8bit, con il file prova.bmp che ha una palette a 4bit. :yup:

Ultima modifica effettuata da Carlo il 21/09/2021 alle 18:43


in programmazione tutto è permesso
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1284
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 22:54
Lunedì, 20/09/2021
Mi controlli se il tuo sistema carica e stampa questi files?

https://we.tl/t-12H8Stb3Ma

bandind2_BlackWhite.bmp (il tuo file originale di test)
bandind2_WhiteBlack.bmp (il tuo file originale di test con la palette invertita)

elle rovesciata HeaderBW.bmp (creata con .Net ma Header di bandind2_BlackWhite.bmp)
elle rovesciata HeaderWB.bmp (creata con .Net ma Header di bandind2_WhiteBlack.bmp)



in programmazione tutto è permesso
PM Quote
Avatar
bernie (Normal User)
Pro


Messaggi: 164
Iscritto: 23/10/2019

Segnala al moderatore
Postato alle 16:38
Martedì, 21/09/2021
Il sistema carica e stampa ( a secco) tutte le 4 grafiche.

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1284
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 18:38
Martedì, 21/09/2021
Bene. :k:
Anche la palette positiva e negativa viene rispettata? :-?
Le info che hai sono sufficienti per procedere? :-?


in programmazione tutto è permesso
PM Quote
Avatar
bernie (Normal User)
Pro


Messaggi: 164
Iscritto: 23/10/2019

Segnala al moderatore
Postato alle 19:04
Martedì, 21/09/2021
Le palette positiva e negativa vengono rispettate.
Pensavo di procedere in questa maniera, prendere l'header di una grafica del sistema e usarla come base. Poi modificare i dati delle dimensioni dei bmp.
A questo punto il primo scoglio è, usare il sistema che hai postato per stirare le grafiche va benissimo, però il limite dei moltiplicatori interi mi blocca. Altra possibilità è usare le GDI+ per stirare le grafiche riconvertirle a 8 bpp, applicare le altre trasformazioni( tagli vari) e alla fine applicare la conversione dell'Header.

PM Quote
Avatar
bernie (Normal User)
Pro


Messaggi: 164
Iscritto: 23/10/2019

Segnala al moderatore
Postato alle 12:33
Sabato, 25/09/2021
C'è qualcosa che non capisco
Sto provando ad  applicare la trasformazione dell'header anche alla parte dove creo la L rovesciata.
Visto che l'header del bmp che utilizzo è 8bpp ho modificato il codice in maniera da creare il bmp a 8 bpp ( verrà più grande ma non interessa per il momento)
A questo punto , ho creato la palette per il mio bmp uguale a quella della grafica di cui vado a copiare l'header.
Creo la mia grafica e poi le modifico l'header , copiandogli sopra l'header del bmp "originale del sistema" e modificando i valori delle dimensioni del bmp .

Tutto bene , c'è solo 1 cosa che non funziona , finora ho sempre usato una palette invertita rispetto a quella che devo usare ora e quindi lo sfondo del bmp era bianco , adesso invece avendo invertito la palette è nero .
Nell'esempio di Carlo per creare i rettangoli
Codice sorgente - presumibilmente C# / VB.NET

  1. ReDim colorValuesH(bytesH - 1)         'un vettore adeguato con tutti zeri (bianco)



però adesso in base alla nuova palette zero è nero , quindi dovrei avere tutti 255, ma non ho capito come fare .
Grazie  

Ultima modifica effettuata da bernie il 25/09/2021 alle 12:35
PM Quote
Pagine: [ 1 2 3 4 5 ] Precedente | Prossimo