Oppure

Loading
07/08/21 19:40
bernie
Non sono quindi le operazioni che faccio alla grafica, ma il solo salvataggio.
Se creo una grafica bmp,4bpp,360x360dpi, posso ruotarla, ingrandirla, tagliarla senza che i parametri cambino, quando la vado a salvare devo specificare in che formato la voglio salvare.
aaa
07/08/21 21:17
Carlo
Postato originariamente da bernie:

Non sono quindi le operazioni che faccio alla grafica, ma il solo salvataggio.
Se creo una grafica bmp,4bpp,360x360dpi, posso ruotarla, ingrandirla, tagliarla senza che i parametri cambino, quando la vado a salvare devo specificare in che formato la voglio salvare.

Esatto :k:
è un parametro del contenitore (formato) di salvataggio, non di come è reppresentata la bitmap internamente, se l'immagine è a 8bpp, sia che la salvi in TIF o che la salvi in BMP sempre a 8bpp resta, poi ci sono i contenitori (formati) che sono sempre a 24bpp come il JPG o 8bpp come il GIF, ecc.
Ultima modifica effettuata da Carlo 07/08/21 21:45
in programmazione tutto è permesso
08/08/21 6:37
bernie
Quindi, visto che devo fare varie operazioni alla grafica prima di salvarla, sarebbe furbo usare un formato che non sia troppo pesante e poi solo alla fine convertirlo nel formato con le caratteristiche che mi servono.
Possibile?
aaa
08/08/21 11:11
Carlo
ci sono dei pro e dei contro.

se le operazioni sono di riscalatura, ritaglio, rotazioni non multiple di 90° con matenimento della qualità usando algoritmi di antialias e scalatura avanzati, si entra in un mondo dove la matematica avanzata la fa da padrone, non alla portata del programmatore medio.
per questo ci sono le GDI+ che contemplano praticamente tutto e ti risolvono i problemi. Ma come sai operano solo con immagini a pixel non indicizzati, nel tuo caso si impongono delle conversioni.

se le operazioni sono semplici, ma con parametri rigidi come i tuoi, forse conviene operare sui byte senza aiuti.

L'unico vero problema, ma forse sono io che non ho le competenze adeguate, è la creazione della palette personalizzata quando si converte un'immagine a pixel non indicizzati in un'immagine a pixel indicizzati.

Non va trascurato il tempo, se le immagini sono molto grandi, la conversione tra i formati di pixel è onerosa.
Ultima modifica effettuata da Carlo 08/08/21 11:16
in programmazione tutto è permesso
08/08/21 15:30
bernie
Abbastanza chiaro.
Ho iniziato a scrivere il programma sfruttando anche i preziosi insegnamenti di Carlo(grazie) ma ovviamente ci sono dei problemi che non capisco. Ho provato ogni singolo blocco del programma separatamente e funzionano tutti, adesso che li sto componendo , iniziano i problemi strani .
Allego il codice incriminato
larghezzapixel = Math.Truncate(larghezzamm * mmpixel) - 1                         'converto le dimensioni del pannello da mm a pixel 
            altezzapixel = Math.Truncate(altezzamm * mmpixel) - 1
            framepixel = Math.Truncate(framemm * mmpixel) - 1
            gappixel = Math.Truncate(gapmm * mmpixel) - 1
            frontestampa = (1000 * nteste) - 1
            Dim origineH, origineW, fineH, fineW As Double
            Dim nome As String
            fineW = frontestampa
            
                For i = 0 To 3
                    Select Case i

                        Case 0                                  'primo lato verticale (lato sinistro)
                            origineH = 0                        'queste sono le dimensioni della grafica bianca 
                            origineW = 0
                            fineH = altezzapixel - frontestampa
                            nome = "latosx"
                            rettangolo(origineW, origineH, fineW, fineH, fineW, (altezzapixel - frontestampa), nome, 0)           ' rettangolo bianco 
                            rettangolo(gappixel, gappixel, fineW, fineH, fineW, (altezzapixel - frontestampa), nome, 15)          ' rettangolo nero

                        Case 1                                  'primo lato orrizzontale (superiore)
                            origineH = 0                        'queste sono le dimensioni della grafica bianca
                            origineW = 0
                            fineH = larghezzapixel - frontestampa
                            nome = "superiore"
                            rettangolo(origineW, origineH, fineW, fineH, fineW, (larghezzapixel - frontestampa), nome, 0)           ' rettangolo bianco 
                            rettangolo(gappixel, gappixel, fineW, fineH, fineW, (larghezzapixel - frontestampa), nome, 15)          ' rettangolo nero

                        Case 2                                  'secondo lato verticale (lato destro)
                            origineH = 0                        'queste sono le dimensioni della grafica bianca
                            origineW = 0
                            nome = "latodx"
                            rettangolo(origineW, origineH, fineW, fineH, fineW, (altezzapixel - frontestampa), nome, 0)           ' rettangolo bianco 
                            rettangolo(gappixel, gappixel, fineW, fineH, fineW, (altezzapixel - frontestampa), nome, 15)          ' rettangolo nero

                        Case 3                                  'secondo lato orrizzontale (base)
                            origineH = 0                        'queste sono le dimensioni della grafica bianca
                            origineW = 0
                            nome = "base"
                            rettangolo(origineW, origineH, fineW, fineH, fineW, (larghezzapixel - frontestampa), nome, 0)           ' rettangolo bianco 
                            rettangolo(gappixel, gappixel, fineW, fineH, fineW, (larghezzapixel - frontestampa), nome, 15)          ' rettangolo nero

                    End Select

                Next        
            
    End Sub

    Sub rettangolo(x1 As UInt32, y1 As UInt32, x2 As UInt32, y2 As UInt32, xgrafica As UInt32, ygrafica As UInt32, name As String, colore As Byte)
        Dim immagine As New Bitmap(xgrafica, ygrafica, Imaging.PixelFormat.Format4bppIndexed)
        immagine.SetResolution(360, 360)
        ' 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
        ' limite valori
        x1 = Math.Truncate(x1 / 2)
        x2 = Math.Truncate(x2 / 2)
        If x1 >= immagine.Width Then x1 = immagine.Width - 1
        If x2 >= immagine.Width Then x2 = immagine.Width - 1
        If y1 >= immagine.Height Then y1 = immagine.Height - 1
        If y2 >= immagine.Height Then y2 = immagine.Height - 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 * immagine.Width                 'calcolo l'indice
                colorValues(ind) = colore
            Next
        Next
        System.Runtime.InteropServices.Marshal.Copy(colorValues, 0, ptr, bytes)
        immagine.UnlockBits(bmpData)                                                'sblocco bit
        immagine.Save("C:\" & name & ".bmp", Imaging.ImageFormat.Bmp)
        immagine.Save("C:\" & name & ".tiff", Imaging.ImageFormat.Tiff)
        immagine.Dispose()
    End Sub


Provo a spiegare cosa stavo tentando di fare
Devo creare 4 grafiche ,in pratica un rettangolo bianco con al suo interno in una data posizione un rettangolo nero( poi dovrò associare al nero un determinato valore essendo un 4bpp ma utilizzato solo 3 bpp)ogni grafica ha alcuni parametri uguali alle altre e altri diversi .Avevo pensato di creare una Sub che si incarica di fare tutto , io le passo ogni volta i dati e poi la chiamo 4 volte. Dopo ogni chiamata salvo la grafica con un determinato nome .
Tutte le volte mi da errore "System.IndexOutOfRangeException: 'Indice oltre i limiti della matrice.'"
nella riga "colorValues(ind) = colore"
Carlo mi ha sempre detto che se voglio una grafica da 1000 pixel devo scrivere 999 perchè viene contato anche lo 0 , infatti quando dichiaro le dimensioni sottraggo 1 .
Però mi da errore .....Sicuramente mi sono dormito qualcosa .
Grazie
Ultima modifica effettuata da bernie 08/08/21 15:31
aaa
09/08/21 10:00
Carlo
La prime cose da sapere per verificare quanto hai scritto, sono i valori in mm a noi sconosciuti.

Quando sarà risolto l'errore "System.IndexOutOfRangeException: 'Indice oltre i limiti della matrice.'", ad ogni case generi due rettangoli, ma i rettangoli non finiranno nella stessa immagine, il rettangolo bianco viene creato in una bitmap e salvato, poi il rettangolo nero viene creato in un'altra bitmap e sovrascrive il file dove c'era il rettangolo bianco.

Stessa cosa se analizzi il for, non cambiando mai il nome i files vengono sovrascritti e alla fine ne troverai solo due...

Se mi metti in condizione di provarlo con i valori che hai usato tu...
Ultima modifica effettuata da Carlo 09/08/21 10:32
in programmazione tutto è permesso
09/08/21 11:17
bernie
Hai ragione, larghezzamm 1000, altezzamm 2000, framemm65,gapmm5, mmpixel 14,17
Perché dici che non cambio nome? Ogni case ha un valore diverso di nome che passo alla sub.
aaa
09/08/21 15:27
Carlo
Postato originariamente da bernie:


Perché dici che non cambio nome? Ogni case ha un valore diverso di nome che passo alla sub.


Ho guardato meglio, è scritto in grigetto, si il nome lo cambi, resta l'errore che all'interno di un case richiami due volte la routine rettangolo che salva due volte con lo stesso nome i due rettangoli creati su due bitmap diverse, di fatto troverai salvato solo il secondo rettangolo.

Entro domani faccio una verifica su VS, solo leggendo non posso dire di più.
in programmazione tutto è permesso