Oppure

Loading
11/06/21 4:44
Pino1946
Buongiorno Carlo,

allora, non ho molto perchè, come dicevo, mi sono appena interessato a GdiPlus e ho scaricato (e buttato) diverso materiale perchè non ci ho capito un'acca (... colpa mia, è chiaro !).

Quello che al momento ho:

1 - stretch (e simili) ... che ho capito come funziona, ma il risultato non è soddisfacente (al riguardo dell'OCR),

StretchBlt Picture1.hdc, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, picDc, 0, 0, picWidth, picHeight, vbSrcCopy

2 - il codice che allego (trovato online) che non ho capito bene come funzioni:

_____________________________________________________

Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
Private Type GdiplusStartupInput
GdiplusVersion As Long
DebugEventCallback As Long
SuppressBackgroundThread As Long
SuppressExternalCodecs As Long
End Type
Private Type EncoderParameter
GUID As GUID
NumberOfValues As Long
type As Long
Value As Long
End Type
Private Type EncoderParameters
Count As Long
Parameter As EncoderParameter
End Type

Private Declare Function GdiplusStartup Lib "GDIPlus" (token As Long, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As Long
Private Declare Function GdiplusShutdown Lib "GDIPlus" (ByVal token As Long) As Long
Private Declare Function GdipCreateBitmapFromHBITMAP Lib "GDIPlus" (ByVal hbm As Long, ByVal hpal As Long, Bitmap As Long) As Long
Private Declare Function GdipDisposeImage Lib "GDIPlus" (ByVal Image As Long) As Long
Private Declare Function GdipSaveImageToFile Lib "GDIPlus" (ByVal Image As Long, ByVal filename As Long, clsidEncoder As GUID, encoderParams As Any) As Long
Private Declare Function CLSIDFromString Lib "ole32" (ByVal str As Long, id As GUID) As Long

Public Sub SaveJPG(ByVal pict As StdPicture, ByVal filename As String, Optional ByVal Quality As Byte = 100) ' ----==== SaveJPG ====----
Dim tSI As GdiplusStartupInput
Dim lRes As Long
Dim lGDIP As Long
Dim lBitmap As Long

tSI.GdiplusVersion = 1 ' Initialize GDI+
lRes = GdiplusStartup(lGDIP, tSI)

If lRes = 0 Then
lRes = GdipCreateBitmapFromHBITMAP(pict.Handle, 0, lBitmap) ' Create the GDI+ bitmap from the image handle

If lRes = 0 Then
Dim tJpgEncoder As GUID
Dim tParams As EncoderParameters

CLSIDFromString StrPtr("{557CF401-1A04-11D3-9A73-0000F81EF32E}";), tJpgEncoder ' Initialize the encoder GUID

tParams.Count = 1 ' Initialize the encoder parameters
With tParams.Parameter ' Quality
CLSIDFromString StrPtr("{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}";), .GUID ' Set the Quality GUID
.NumberOfValues = 1
.type = 4
.Value = VarPtr(Quality)
End With

lRes = GdipSaveImageToFile(lBitmap, StrPtr(filename), tJpgEncoder, tParams) ' Salva

GdipDisposeImage lBitmap ' Destroy the bitmap
End If

GdiplusShutdown lGDIP ' Shutdown GDI+
End If

If lRes Then
Err.Raise 5, , "Cannot save the image. GDI+ Error:" & lRes
End If

End Sub

Private Sub Form_Load()
Call SaveJPG(StdPicture, "c:\Prova.bmp", 100)
End Sub
_____________________________________________________

Premetto che, quello che mi ha colpito, è la frase "Ho risolto usando una classe della gdiplus. Quindi salvo l'immagine in formato jpg impostando nel comando anche i DPI che nel mio caso sono 300 e 300", postato da "untipo".

Auguro una buona giornata:cheer:
aaa
11/06/21 11:53
Carlo
Ciao, premetto che non ho una risposta pronta in VB6, e usare GDI+ in VB6 è fattibile ma a quale scopo?
Ammetti che il codice lo hai copiato, e se hai un progetto VB6 che devi mantenere ne capisco la ragione.
Anche se hai la voglia di usare VB6 per forza perché vuoi sperimentare cosa riesci a fare, ancora lo capisco.

Invece se vuoi usare GDI+ per ottenere lo scopo che ti preme, scalare un'immagine a diversi DPI, per ottenere un'immagine risultante con risoluzione maggiore per darla in pasto ad un OCR, sappi che i linguaggi .Net sfruttano la GDI+ in modo nativo.

Ecco come è il codice in VB .Net che fa molto di più di quello che hai postato in VB6:

'' cambia DPI
Dim bmp1 As New Bitmap("bmpIn.bmp") ' bmpIn nome immagine da caricare
Dim nuovabmp As New Bitmap(bmp1.Width * 4, bmp1.Height * 4) ' 4x (per passare da 72 a 300 DPI)
Dim g1 As Graphics = Graphics.FromImage(nuovabmp) ' nuovabmp come layer grafico
g1.InterpolationMode = InterpolationMode.HighQualityBicubic ' alta qualità scaling
g1.DrawImage(bmp1, 0, 0, nuovabmp.Width, nuovabmp.Height) ' scalatura
nuovabmp.SetResolution(300, 300) ' set DPI
nuovabmp.Save("bmp300HQbicubic.bmp", Drawing.Imaging.ImageFormat.Bmp) ' salvo il risultato


in allegato l'eseguibile con una bmp da 96DPI, se esegui BMPsuBMP.exe la porta a 4 volte la risoluzione e la salva a 300DPI

Prova una delle tue immagini rinominandole, per vedere se il programma fa quello che cerchi.
Naturalmente una volta che usi .Net altre migliaia di possibilità a livello grafico ti si schiudono, permettendoti di usare il tempo per sviluppare software, invece che spendere tempo ad adattare in VB6 cose per il quale non è stato progettato.

Non ti voglio forzare a fare nulla di quello che non ti piace, anzi se me ne dai motivo sono disposto a riesumare un mio PC WinXP con VB6, per aiutarti.
Ultima modifica effettuata da Carlo 11/06/21 12:36
in programmazione tutto è permesso
11/06/21 12:15
Pino1946
Ciao Carlo,

grazie per la cortesia !

Al momento sono in giro e, con calma, leggerò per bene e rifletterò.

Iniziare col VB.Net, credo comunque di escluderlo perchè sarebbe troppo "vasto" per me.

L'allegato (BMPsuBMP.exe) che potrebbe aiutarmi ... non lo vedo, come faccio a scaricarlo ?

Poi, ti farò sapere ... se ti interessa !

Per il momento, ancora un grande "GRAZIE" !

Buona giornata
aaa
11/06/21 14:35
Carlo
Sotto al mio post, devi vedere Carlo ha allegato un file...
Ma da cellulare, per vederlo devi caricare il sito in modalità classica.

Ho aggiunto due righe di codice in modo che hai un programma che carica qualsiasi file grafico, puoi cambiare zoom, qualità di scaling, DPI, e salvare in PNG, BMP, JPG e TIFF, puoi vedere in tempo reale quello che fai.

In VB .Net è tutto facile, dissento con la tua affermazione: non se ne parla di passare a .Net perché è troppo vasto.
Se resti a VB6, i tuoi programmi sono destinati a produrre risultati incerti sotto Win10, gli sforzi che metti in campo non sono ripagati, invece se li canalizzi in .Net, sono immediatamente percepibili.

Non è una predica, ma un tentativo di farti spendere il tempo in una direzione che ti darà soddisfazione... :heehee:
Pensa quanto codice avresti dovuto scrivere in VB6 per fare il programma che ti ho postato.
Ultima modifica effettuata da Carlo 12/06/21 17:05
in programmazione tutto è permesso
14/06/21 10:13
Pino1946
Ciao Carlo,

non ti ho dimenticato: non dimentico mai uno che mi aiuta e che reputo un amico, anche se lontano !

Ho avuto un problema col pc, perciò non riuscivo nemmeno a vedere il tuo link (da pc) e cliccando su "versione classica", mi dava messaggi di errore !

Sono d'accordissimo con te, al riguardo dei consigli che mi hai dato, ma preciso che:

- non vendo ma, come te (sicuramente), aiuto gli amici che hanno un qualche problema e, come dicevo, recuperare software, installarlo (pare facile ma, a volte, installa qua, installa la, installa gli aggiornamenti, etc., etc.), imparare un nuovo linguaggio ..., può diventare pesante e, per una o due volte che ne avrei bisogno ... capisci ?

- ... come dicevamo in tedesco "... me fà male 'a capa" ! Parli il tedesco ? Scherzo !

Al riguardo della tua routine, funziona bene, solo che purtroppo il risultato, anche a 300 dpi, in quanto a OCR lascia a desiderare; quindi, presumo che ciò che ho letto al riguardo dei 300 dpi, non sempre vada bene.

Fa niente, mi accontenterò dell'OCR che passa il convento !

Grazie ancora per le tue premure e, semmai, avessi bisogno di me (nel mio piccolo) sicuramente cercherei di ricambiare !

Buona giornata
aaa
15/06/21 8:49
Carlo
Non so come usi l'OCR, se stampi un'immagine contenente testo e poi la passi ad uno scanner con l'OCR, i DPI contano, ma se li hai aumentati artificiosamente, non è che crei quello che non esiste.:asd:
Se incolli un'immagine in un documento Word e poi usi l'OCR di Word, i DPI non contano perché nel documento Word puoi ridimensionare l'immagine a piacere (ne cambi i DPI), in questo caso conta la risoluzione in pixel dell'immagine originale, più è definita e precisa meglio è.
Se usi un OCR che carica un'immagine, quello che conta è la risoluzione in pixel dell'immagine, i DPI non contano, in questo caso cambiare la risoluzione in pixel dell'immagine originale, modificano la risposta dell'OCR, ma non ti aspettare grandi differenze.
Per esempio hai un'immagine che contiene un testo ben definito ma che usa un font piccolo, quando lo passi all'OCR magari in viene riconosciuto come m, in questo caso passare l'immagine nel mio programma, scalare a 2x con ricampionamento HQ, può risolvere il problema.

Ciao, alla prossima.
Ultima modifica effettuata da Carlo 15/06/21 11:10
in programmazione tutto è permesso
17/06/21 14:40
Pino1946
Eccomi !

Allora, il progetto è di catturare una parte dello schermo (col testo), salvarla in bmp, trasformarla in tif (alcuni software lavorano solo col tif), darla in pasto ai software di OCR e, il risultato, farlo leggere da Merlino.

Il progetto è molto più vasto ma, quanto sopra, è il "problema" e/o fulcro della situazione.

Ho provato con Tesseract 5.0, ABBYY 15.0 e altri: vanno bene ma, come dicevi tu, c'è sempre un carattere o gruppo di caratteri che non vengono riconosciuti bene e, a meno di miracoli, per il momento sarei orientato al classico MODI, almeno sarei autonomo e il pgm sarebbe più leggero ... appena trovo un po' più di tempo !

A proposito, sapresti dirmi (magari con riga di esempio e API corrispondente) come disegnare un rettangolo sul desktop ... con VB6 ?

La parte di schermo da catturare, l'ho già fatta e funziona bene, vorrei però aggiungere un "qualcosa per gli occhi" di chi userà 'sta routine ... quando l'avrò finita !

A presto !
aaa
17/06/21 18:50
Carlo
In VB6?, sicuramente ho scritto qualcosa tempo fa, ma la memoria scricchiola, difficile rispondere senza aprire qualche vecchio progetto.
In VB.Net ho pubblicato OCR_FromScreen:

pierotofy.it/pages/sorgenti/dettagli/19620-OCR=FromScreen/

Per scegliere la porzione dello schermo da catturare ho utilizzato la proprietà TransparencyKey, che permette di rendere trasparente un colore a scelta.

In VB6 sicuramente si può fare importando GDI+, ma al solito perché complicarsi la vita?
Spero che trovi qualche volenteroso che ancora usa VB6 e ha le risposte che ti servono, personalmente dovrei provare e non ho più VB6 in questo PC.

Anche disegnare un rettangolo sopra al desktop non è difficile in .Net, ti ho allegato un eseguibile provalo, primo clik = punto di partenza di un rettangolo (tasto sinistro mouse), poi ti muovi con il mouse e vedrai il rettangolo con tanto di coordinate, secondo clik = punto di fine, il rettangolo resta visualizzato, invece se clicchi con il tasto destro il programma si chiude.

Attenzione il programma non fa nulla di utile e non è perfetto, è solo per saggiare le potenzialità di .Net, l'ho scritto in 2 minuti, e occupa 10 righe.
Ultima modifica effettuata da Carlo 18/06/21 8:07
in programmazione tutto è permesso