07/07/21 14:04
Carlo
Ultima modifica effettuata da Carlo 07/07/21 21:25
in programmazione tutto è permesso
For ind = 0 To bytes - 1 ' la lunghezza del vettore colorValues(ind) = 200 ' un valore qualsiasi 0...255 Next
' puntatore all'indirizzo di memoria del primo byte. Dim ptr As IntPtr = bmpData.Scan0 ' un vettore che conterrà tutti i bytes della bitmap. Dim bytes As Long = Math.Abs(bmpData.Stride) * immagine.Height ' calcolo dei bytes necessari Dim colorValues(bytes - 1) As Byte Dim ind As Long Dim app As Long Dim app2 As Long app = (larghezza *(altezza-altezza1) ' calcolo l'area bianca superiore For ind = 0 To app - 1 ' coloro di bianco l'area bianca superiore colorValues(ind) = 255 Next For app2 = app To bytes Step Math.Abs(bmpData.Stride) For ind = app2 To app2 + (larghezza-larghezza1) - 1 ' coloro di bianco la fascia sinistra colorValues(ind) = 255 Next For ind = app2 + (larghezza-larghezza1) - 1 To (app2 + larghezza) - 1 colorValues(ind) = 255 - (32 * livello) ' a ogni pixel scrivo il valore di profondità per avere il livello voluto Next Next ' ripristino vettore su immagine System.Runtime.InteropServices.Marshal.Copy(colorValues, 0, ptr, bytes) immagine.UnlockBits(bmpData) ' sblocco bit immagine.SetResolution(360, 360) immagine.Save("C:\Users\bernie\test8bpp_livello.bmp", Imaging.ImageFormat.Bmp) End Sub
Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim sw As New Stopwatch Dim larghezza As UInt16 = 5000 ' 0...4999, solo positivi Dim altezza As UInt16 = 2500 ' 0...2499, solo positivi Dim immagine As New Bitmap(larghezza, altezza, Imaging.PixelFormat.Format8bppIndexed) ' creo una palette con 256 livelli di grigio Dim palette As Imaging.ColorPalette = immagine.Palette For i = 0 To palette.Entries.Length - 1 palette.Entries(i) = Color.FromArgb(i, i, i) Next i ' associo la palette creata alla bitmap 8bpp, ' i valori 0...255 ora corrispondono alla scala dal nero al bianco immagine.Palette = palette ' blocco i bit della bitmap per poter lavorare direttamente su un vettore di bytes Dim area As Rectangle = New Rectangle(0, 0, immagine.Width, immagine.Height) Dim bmpData As Imaging.BitmapData = immagine.LockBits(area, Imaging.ImageLockMode.ReadWrite, immagine.PixelFormat) ' puntatore all'indirizzo di memoria del primo byte. Dim ptr As IntPtr = bmpData.Scan0 ' un vettore che conterrà tutti i bytes della bitmap. Dim bytes As Integer = Math.Abs(bmpData.Stride) * immagine.Height ' calcolo dei bytes necessari Dim colorValues(bytes - 1) As Byte sw.Restart() ' avvio il conteggio del tempo rettangolo(0, 0, 4999, 299, Math.Abs(bmpData.Stride), altezza, colorValues, 255) ' rettangolo bianco superiore rettangolo(0, 300, 299, 2499, Math.Abs(bmpData.Stride), altezza, colorValues, 100) ' rettanglo grigioscuro sinistro rettangolo(300, 300, 4999, 2499, Math.Abs(bmpData.Stride), altezza, colorValues, 200) ' rettangolo grigio Me.Text = "Scrittura Bytes in: " & sw.ElapsedMilliseconds & "ms." ' mostro il tempo impiegato ' ripristino vettore su immagine System.Runtime.InteropServices.Marshal.Copy(colorValues, 0, ptr, bytes) immagine.UnlockBits(bmpData) ' sblocco bit immagine.Save("prova8bpp.bmp", Imaging.ImageFormat.Bmp) End Sub Sub rettangolo(x1 As UInt16, y1 As UInt16, x2 As UInt16, y2 As UInt16, larghezza As UInt32, altezza As UInt16, vettore() As Byte, colore As Byte) ' limite valori If x1 >= larghezza Then x1 = larghezza - 1 If x2 >= larghezza Then x2 = larghezza - 1 If y1 >= altezza Then y1 = altezza - 1 If y2 >= altezza Then y2 = altezza - 1 For colonna = x1 To x2 For riga = y1 To y2 Dim ind As UInt32 = colonna + riga * larghezza 'calcolo l'indice vettore(ind) = colore Next Next End Sub End Class
Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim sw As New Stopwatch Dim larghezza As UInt32 = 4000 ' 0...3998, solo positivi, due a due Dim altezza As UInt32 = 130000 ' 0...129999, solo positivi Dim immagine As New Bitmap(larghezza, altezza, Imaging.PixelFormat.Format4bppIndexed) ' creo una palette con 16 livelli di grigio Dim palette As Imaging.ColorPalette = immagine.Palette For i = 0 To palette.Entries.Length - 1 palette.Entries(i) = Color.FromArgb(i * 17, i * 17, i * 17) Next i ' associo la palette creata alla bitmap 4bpp, ' i valori 0...15 ora corrispondono alla scala dal nero al bianco immagine.Palette = palette ' blocco i bit della bitmap per poter lavorare direttamente su un vettore di bytes Dim area As Rectangle = New Rectangle(0, 0, immagine.Width, immagine.Height) Dim bmpData As Imaging.BitmapData = immagine.LockBits(area, Imaging.ImageLockMode.ReadWrite, immagine.PixelFormat) ' puntatore all'indirizzo di memoria del primo byte. Dim ptr As IntPtr = bmpData.Scan0 ' un vettore che conterrà tutti i bytes della bitmap. Dim bytes As Integer = Math.Abs(bmpData.Stride) * immagine.Height ' calcolo dei bytes necessari Dim colorValues(bytes - 1) As Byte sw.Restart() ' avvio il conteggio del tempo rettangolo(0, 0, 4000, 299, Math.Abs(bmpData.Stride), altezza, colorValues, 15) ' rettangolo bianco superiore rettangolo(0, 300, 298, 130000, Math.Abs(bmpData.Stride), altezza, colorValues, 8) ' rettanglo grigioscuro sinistro rettangolo(300, 300, 4000, 130000, Math.Abs(bmpData.Stride), altezza, colorValues, 10) ' rettangolo grigio Me.Text = "Scrittura Bytes in: " & sw.ElapsedMilliseconds & "ms." ' mostro il tempo impiegato ' ripristino vettore su immagine System.Runtime.InteropServices.Marshal.Copy(colorValues, 0, ptr, bytes) immagine.UnlockBits(bmpData) ' sblocco bit immagine.Save("prova4bpp.bmp", Imaging.ImageFormat.Bmp) End Sub Sub rettangolo(x1 As UInt32, y1 As UInt32, x2 As UInt32, y2 As UInt32, larghezza As UInt32, altezza As UInt32, vettore() As Byte, colore As Byte) ' limite valori x1 = Math.Truncate(x1 / 2) x2 = Math.Truncate(x2 / 2) If x1 >= larghezza Then x1 = larghezza - 1 If x2 >= larghezza Then x2 = larghezza - 1 If y1 >= altezza Then y1 = altezza - 1 If y2 >= altezza Then y2 = altezza - 1 ' a 4bpp scrivo 2 pixel adiacenti alla volta colore = colore + colore * 16 ' valore per due pixel uguali For colonna As UInt32 = x1 To x2 For riga As UInt32 = y1 To y2 Dim ind As UInt32 = colonna + riga * larghezza 'calcolo l'indice vettore(ind) = colore Next Next End Sub End Class