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.
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
è 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?
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.
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
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
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...
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.
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.
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