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 - File bmp
Forum - C# / VB.NET - File bmp - Pagina 6

Pagine: [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ] Precedente | Prossimo
Avatar
Carlo (Member)
Guru


Messaggi: 1097
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 15:06
Lunedì, 26/07/2021
allega: cerchiogreyscale8bpp.bmp


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


Messaggi: 149
Iscritto: 23/10/2019

Segnala al moderatore
Postato alle 15:08
Lunedì, 26/07/2021
Ecco , niente di speciale


bernie ha allegato un file: cerchiogreyscale8bpp.zip (22821 bytes)
Clicca qui per scaricare il file
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1097
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 17:49
Lunedì, 26/07/2021
L'esempio che hai postato ha una falla logica, sempre che io abbia bene interpretato cosa vuoi fare.
Il problema sta nel fatto che l'immagine: cerchiogreyscale8bpp.bmp con palette a 256 livelli di grigio la converti subito a 4bpp, facendo questo perdi i valori originali dei livelli che poi vorresti convertire a 4bpp.
L'esempio che segue corregge il problema, e ti fa impostare una palette come desideri senza fare una sequenza di iff.
Le righette che vedi ci sono perché non hai calcolato i valori correttamente.
Codice sorgente - presumibilmente VB.NET

  1. ' da 8bpp a 4bpp con palette a 3bit
  2.        Dim bmp8bpp As New Bitmap("C:\cerchiogreyscale8bpp.bmp")
  3.         ' blocco i bit della bitmap    
  4.         Dim area8 As Rectangle = New Rectangle(0, 0, bmp8bpp.Width, bmp8bpp.Height)
  5.         Dim bmpData8 As System.Drawing.Imaging.BitmapData = bmp8bpp.LockBits(area8, Drawing.Imaging.ImageLockMode.ReadWrite, bmp8bpp.PixelFormat)
  6.         Dim ptr8 As IntPtr = bmpData8.Scan0 ' puntatore all'indirizzo di memoria del primo byte.
  7.         Dim bytes8 As Integer = Math.Abs(bmpData8.Stride) * bmp8bpp.Height ' calcolo dei bytes necessari
  8.         Dim colorValues(bytes8 - 1) As Byte ' un array che conterrà tutti i bytes della bitmap.
  9.         ' nel vettore colorValues metto i dati dalla locazione ptr che rappresentano bmp8bpp
  10.         System.Runtime.InteropServices.Marshal.Copy(ptr8, colorValues, 0, bytes8)
  11.      
  12.  
  13.         ' dichiaro bmp4bpp
  14.         Dim bmp4bpp As New Bitmap(bmp8bpp.Width, bmp8bpp.Height, Imaging.PixelFormat.Format4bppIndexed)
  15.         ' blocco i bit della bitmap    
  16.         Dim area4 As Rectangle = New Rectangle(0, 0, bmp4bpp.Width, bmp4bpp.Height)
  17.         Dim bmpData4 As System.Drawing.Imaging.BitmapData = bmp4bpp.LockBits(area4, Drawing.Imaging.ImageLockMode.ReadWrite, bmp4bpp.PixelFormat)
  18.         'creo una palette con 8 livelli di grigio a piacere, qui scegli l'aspetto dell'immagine con i colori scalati
  19.         Dim palette8 As Imaging.ColorPalette = bmp4bpp.Palette
  20.         palette8.Entries(0) = Color.FromArgb(200, 200, 200)
  21.         palette8.Entries(1) = Color.FromArgb(10, 10, 10)
  22.         palette8.Entries(2) = Color.FromArgb(20, 20, 20)
  23.         palette8.Entries(3) = Color.FromArgb(30, 30, 30)
  24.         palette8.Entries(4) = Color.FromArgb(100, 100, 100)
  25.         palette8.Entries(5) = Color.FromArgb(101, 101, 101)
  26.         palette8.Entries(6) = Color.FromArgb(200, 200, 200)
  27.         palette8.Entries(7) = Color.FromArgb(130, 130, 130)
  28.         ' associo la palette creata alla bitmap 4bpp,
  29.         ' i valori 0...7 ora corrispondono alla scala arbitraria creata
  30.         bmp4bpp.Palette = palette8
  31.         Dim ptr4 As IntPtr = bmpData4.Scan0
  32.         Dim bytes4 As Long = Math.Abs(bmpData4.Stride) * bmp4bpp.Height ' calcolo dei bytes necessari
  33.         Dim levelValues(bytes4 - 1) As Byte
  34.  
  35.         ' nel vettore che rappresenta bmp4bpp ci copio i dati dal vettore che rappresenta bmp8bpp, scalati
  36.         ' scorro i vettori per riga e colonna
  37.  
  38.         For riga = 0 To bmp8bpp.Height
  39.             For colonna = 0 To bmpData8.Stride
  40.                 Dim ind8 As UInt32 = colonna + riga * (bmpData8.Stride - 2)  'calcolo l'indice per il vettore colorValues
  41.                 Dim ind4 As UInt32 = colonna / 2 + riga * (bmpData4.Stride - 1)   'calcolo l'indice per il vettore levelValues
  42.                 levelValues(ind4) = (colorValues(ind8) \ 31.8) + (colorValues(ind8) \ 31.8) * 16
  43.             Next
  44.         Next
  45.    
  46.         ' ripristino vettore su immagine
  47.         System.Runtime.InteropServices.Marshal.Copy(levelValues, 0, ptr4, bytes4)
  48.         bmp4bpp.UnlockBits(bmpData4) ' sblocco bit
  49.         bmp4bpp.SetResolution(360, 360)
  50.         bmp4bpp.Save("C:\remap8bppa3bpp.bmp", Imaging.ImageFormat.Bmp)



levelValues(ind4) = entrambi i pixel uguali, se li vuoi divisi sai come fare.

Ultima modifica effettuata da Carlo il 26/07/2021 alle 17:58


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


Messaggi: 149
Iscritto: 23/10/2019

Segnala al moderatore
Postato alle 19:07
Lunedì, 26/07/2021
Giustissimo , prendo l'immagine a 8bpp e la converto subito a 4bpp, così facendo perdo tutti i livelli di grigio.
Quindi , prendo l'immagine ,blocco i bit nel vettore ( e sono ancora 255 livelli )
Creo un bmp delle stesse dimensioni(pixel) a 4bpp, il numero dei byte sarà la metà visto che 1 byte fa due pixel.
A questo punto tutti i pixel che hanno valore compreso tra (0,0,0) a (10,10,10) nel bmp 8bpp dovranno diventare tutti 0 nel bmp a 3bpp.
Per quello mi servivano tutti gli if , perchè non devo cambiare solo un valore , ma tutti i pixel che cadono dentro un certo intervallo di colore , devono diventare tutti uguali .
Se un pixel ha valore (255,255,255) e il successivo (253,253,253) entrambi con la nuova palette diventano 7 mentre se  il seguente è (240,240,240) diventa 6 . Devo raggruppare tutti i valori della palette a 256 livelli in 8 livelli .
Da (255,255,255) a (223,223,223) diventano 7
Da(222,222,222) a (190,190,190) diventano 6
e via cosi . Ovviamente il range lo devo impostare.

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1097
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 19:56
Lunedì, 26/07/2021
questa riga
Codice sorgente - presumibilmente Plain Text

  1. levelValues(ind4) = (colorValues(ind8) \ 31.8) + (colorValues(ind8) \ 31.8) * 16


fa quello che dici tu senza if

Hai provato l'esempio?


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


Messaggi: 149
Iscritto: 23/10/2019

Segnala al moderatore
Postato alle 20:50
Lunedì, 26/07/2021
Si, ho provato l'esempio ma non posso passarlo al sistema per adesso.
Nel tuo esempio la rimappatura è lineare, a me non serve lineare.

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1097
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 15:23
Martedì, 27/07/2021
Testo quotato

Postato originariamente da bernie:

Si, ho provato l'esempio ma non posso passarlo al sistema per adesso.
Nel tuo esempio la rimappatura è lineare, a me non serve lineare.  


Avevo capito che non ti serve lineare :asd:, ma ho fatto questo ragionamento:
L'immagine in input è a 8bpp e ha una scala di 256 grigi lineare.
Nell'immagine di output a 4bpp dove solo 3bit della palette vengono usati, ci copio i dati scalati linearmente dall'immagine 8bpp.
Ora agendo sulla palette a 3bit, posso scegliere arbitrariamente il livello RGB di ogni valore 0...7 che mi occorre, senza dover per forza restare lineare.
:rotfl:

Ultima modifica effettuata da Carlo il 27/07/2021 alle 21:45


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


Messaggi: 149
Iscritto: 23/10/2019

Segnala al moderatore
Postato alle 8:56
Giovedì, 29/07/2021
non so come quotare il testo , comunque , questo non l'ho capito
"Ora agendo sulla palette a 3bit, posso scegliere arbitrariamente il livello RGB di ogni valore 0...7 che mi occorre, senza dover per forza restare lineare."
Il sistema converte automaticamente un file 8bpp in un 4bpp in questa maniera
Livello in            Livello uscita
      0 – 7            0
      8 - 53           1
      54 – 89         2
      90 – 125       3
      126 – 161     4
      162 – 197     5
      198 – 233     6
      234 - 255      7

Il motivo per cui voglio convertirlo io è per gestire dei file  meno " pesanti" visto le grandi dimensioni dei file.
E anche per poter gestire gli intervalli ,a volte devo usare solo 5 livelli in uscita ,  però questo non ho capito come dici di farlo .
Grazie , scusa se mi spiego male


Ultima modifica effettuata da bernie il 29/07/2021 alle 8:59
PM Quote
Pagine: [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ] Precedente | Prossimo