Oppure

Loading
25/09/21 10:33
bernie
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
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 25/09/21 10:35
aaa
25/09/21 13:13
Carlo
Quando dichiari un vettore conterrà tutti zeri.
Se ora devi disegnare su uno sfondo di zeri, devi mettere un valore più alto di zero, la massima differenza ce l'hai con 255.
Come vedi non ho menzionato colori, perché in un file indicizzato i colori che rappresentano i valori inseriti nel vettore sono definiti nella palette.

Ora hai un vettore con zeri e 255, se nell'header metti quello con la palette BW, gli zeri saranno neri i 255 bianchi, avviene l'inverso se metti l'header WB.

Imports System.IO

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' Valori impostabili
        Dim larghezzamm = 1000
        Dim altezzamm = 2000
        Dim framemm = 70
        Dim gapmm = 70
        Dim mmpixel = 14.17
        Dim nteste = 3
        Dim larghezzapixel = Math.Truncate(larghezzamm * mmpixel) - 1                         'converto le dimensioni del pannello da mm a pixel
        Dim altezzapixel = Math.Truncate(altezzamm * mmpixel) - 1
        Dim framepixel = Math.Truncate(framemm * mmpixel) - 1
        Dim gappixel = Math.Truncate(gapmm * mmpixel) - 1
        Dim frontestampa = (1000 * nteste) - 1
        Dim fineH, fineW As Double
        fineW = frontestampa
        fineH = altezzapixel - frontestampa

        Dim sw As New Stopwatch
        ' una volta definiti i valori l'immagine non cambierà più in dimensioni
        Dim immagineH As New Bitmap(fineW, altezzapixel - frontestampa, Imaging.PixelFormat.Format8bppIndexed)      'immagine per l'altezza
        immagineH.SetResolution(360, 360)
        ' la palette vale quella nell'Header nell'immagine di riferimento:
        ' bandind2_BlackWhite.bmp 0=nero 255=bianco (il fondo della bmp sarà nero)
        ' bandind2_WhiteBlack.bmp 255=nero 0=bianco (il fondo della bmp sarà bianco)

        '************** grafica
        Dim areaH As Rectangle = New Rectangle(0, 0, immagineH.Width, immagineH.Height) ' area di lavoro LockBits
        Dim bmpDataH As Imaging.BitmapData = Nothing ' conterrà i dati della bitmap
        Dim ptrH As IntPtr ' conterrà l'indirizzo di memoria
        Dim bytesH As Integer ' conterrà la dimensione del vettore  
        Dim colorValuesH() As Byte = Nothing ' conterrà il vettore

        'una elle rovesciata di 255
        bmpDataH = immagineH.LockBits(areaH, Imaging.ImageLockMode.ReadWrite, immagineH.PixelFormat)
        ptrH = bmpDataH.Scan0
        bytesH = Math.Abs(bmpDataH.Stride) * immagineH.Height
        ReDim colorValuesH(bytesH - 1)      'un vettore adeguato con tutti zeri
        sw.Restart()
        rettangolo(200, 500, fineW, 700, bmpDataH.Stride, immagineH.Height, colorValuesH, 255) ' bandind2_BlackWhite.bmp 0=nero 255=bianco, bandind2_WhiteBlack.bmp 255=nero 0=bianco
        rettangolo(200, 700, 400, fineH, bmpDataH.Stride, immagineH.Height, colorValuesH, 255) ' bandind2_BlackWhite.bmp 0=nero 255=bianco, bandind2_WhiteBlack.bmp 255=nero 0=bianco
        Me.Text = "una elle rovesciata di 255 tracciata in: " & sw.ElapsedMilliseconds & " ms."
        System.Runtime.InteropServices.Marshal.Copy(colorValuesH, 0, ptrH, bytesH)
        immagineH.UnlockBits(bmpDataH)                                                'sblocco bit
        immagineH.Save("elle rovesciata HeaderBW.bmp", Imaging.ImageFormat.Bmp)

        ' copio tutto l'Header del file d'origine nel file creato
        Dim fsO As New FileStream("bandind2_BlackWhite.bmp", FileMode.Open, FileAccess.Read) ' nero bianco, bandind2_WhiteBlack.bmp bianco nero
        Dim fsS As New FileStream("elle rovesciata HeaderBW.bmp", FileMode.Open, FileAccess.Write) ' stesso nome del file salvato
        Dim br As New BinaryReader(fsO)
        Dim bw As New BinaryWriter(fsS)
        Dim Byteletto As Byte ' lettura Byte
        ' copio pari pari l'header d'origine
        Do While fsO.Position <= &H435 '  fino alla fine all HEX scelto, termine Header di un BMP
            Byteletto = br.ReadByte() ' lettura byte dall'origine
            bw.Seek(CInt(fsO.Position - 1), SeekOrigin.Begin) ' posizione di destinazione
            bw.Write(Byteletto) ' scrittura del byte letto in pari posizione
        Loop

        ' aggiusto i parametri che potrebbero essere variati
        bw.Seek(&H2, SeekOrigin.Begin) ' in posizione &H2 = lunghezza file
        bw.Write(fsS.Length) ' metto la lunghezza del file
        bw.Seek(&H12, SeekOrigin.Begin) ' in posizione &H12 = larghezza
        bw.Write(immagineH.Width) ' scrivo la larghezza
        bw.Seek(&H16, SeekOrigin.Begin) ' in posizione &H16 = altezza
        bw.Write(immagineH.Height) ' scrivo l'altezza
        fsO.Close()
        fsS.Close()
        immagineH.Dispose()

    End Sub

    ' traccia un rettangolo data la sua diagonale, prima coordinata x1,y1 seconda coordinata x2,y2
    ' la larghezza e l'altezza servono per calcolare l'indice e limitare valori fuori range,
    ' non devono differire dalla dimensione del vettore da bitmap. larghezza = bmpData.Stride, altezza = immagine.Height
    ' il vettore va passato per fare in modo che i rettangoli siano scritti nella stessa area grafica
    ' il colore può essere un valore tra 0 e 255
    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
        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 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


allegati i due file dove prelevare l'Header, positivo o negativo
Ultima modifica effettuata da Carlo 25/09/21 13:23
in programmazione tutto è permesso
25/09/21 13:49
bernie
Grazie Carlo
Io pensavo che usando l'header del file di test del sistema fosse la soluzione migliore. Per questo pensavo di dover adattare il mio programma all'header.
Considerando che le grafiche le creo in base alla grafica di test.
È sbagliato il ragionamento?
Grazie
aaa
25/09/21 16:57
bernie
Ho notato che nell'esempio non crei la palette per il bmp , ma usi quella dell'header .
Però se uno l'header del file WB mi ritrovo che stampo il contrario di quello che mi serve .
Devo mettere nel vettore tutti 255
aaa
25/09/21 20:02
Carlo
Postato originariamente da bernie:

Grazie Carlo
Io pensavo che usando l'header del file di test del sistema fosse la soluzione migliore. Per questo pensavo di dover adattare il mio programma all'header.
Considerando che le grafiche le creo in base alla grafica di test.
È sbagliato il ragionamento?
Grazie

Il ragionamento è giusto ma ti ho creato il file di test con la palette invertita per evitari di dover disegnare al contrario.

Postato originariamente da bernie:
Ho notato che nell'esempio non crei la palette per il bmp , ma usi quella dell'header .
Però se uno l'header del file WB mi ritrovo che stampo il contrario di quello che mi serve .
Devo mettere nel vettore tutti 255


Perché perdi tempo a mettere tutti 255? non è meglio usare l'Header WB? Avevi detto che la stampante lo riconosce!!

Mi ripeto, quando crei il vettore, VB .Net mette tutti zeri e quello sarà lo sfondo, se lo sfondo lo vuoi bianco usi la palette con l'Header WB, se lo sfondo lo vuoi nero usi l'Header con la palette BW.

Quando disegni usi sempre il livello 255, se 255 sarà bianco o nero lo decide la palette che hai scelto.

C'è un frangende dove il ragionamento potrebbe essere valido al contrario, i 255 che devi scrivere sono più del 50% dei pixel totali...
Ultima modifica effettuata da Carlo 25/09/21 20:07
in programmazione tutto è permesso
25/09/21 20:13
bernie
È vero, la stampante lo riconosce, ma stamperei in negativo.
Per esempio stamperei una pagina nera con le scritte bianche invece che una pagina bianca con le scritte nere.

aaa
25/09/21 21:21
bernie
O forse no, se il valore del pixel è 255, dovrebbe stamparlo col livello 7 a prescindere dal colore della grafica, questo nel caso che la palette non abbia significato nell'assegnazione dei livelli.
aaa
26/09/21 9:23
Carlo
Postato originariamente da bernie:

O forse no, se il valore del pixel è 255, dovrebbe stamparlo col livello 7 a prescindere dal colore della grafica, questo nel caso che la palette non abbia significato nell'assegnazione dei livelli.


Questa è una domanda che ti ho posto molti post fa, e la ripeto: la stampante tiene conto della palette?

devi fare una prova e stampare i due file di test che ti ho inviato: bandind2_BlackWhite.bmp e bandind2_WhiteBlack.bmp

Se vengono stampati identici, la stampante non tiene conto della palette, e i valori che metti nel vettore per la stampante rappresenteranno sempre lo stesso livello di grigio indipendentemente da come vedi il file su Windows.

Sempre se così fosse, per avere il bianco stampato devi immettere 255.

Il vettore all'inizio contiene tutti zeri (nero) devi scrivere SOLO il bianco (255) che ti serve, evitare di riempire di tutti 255 e poi scrivere gli zeri. Se l'immagie è molto grande perderesti tempo.

Se stabilisci che con la palette a 4bit il livello 7 è sempre bianco, sarebbe fantastico visto che se usi GDI+ quando converti a 8bpp o 4bpp il bianco prende proprio il livello 7, questo significherebbe che il programma che ritenevi che non funzionasse perché il fondo ti diventava grigio, invece per la stampante sarebbe stato bianco.

in programmazione tutto è permesso