Newsgroup: it.comp.lang.visual-basic
Titolo: [HELP] Ridimensionamento immagini

innanzi tutto un saluto a tutti,
e' da tantissimo tempo che leggo questo ng ma e' la prima volta che ci
posto...
Chiedo se un'anima pia puo' svelarmi il modo di ridimensionare un'immagine
sia nel caso che risieda in memoria sia nel caso e' registrato nell'hard
disk come gif o jpg...
Ringrazio in anticipo chiunque voglia rispondermi anche via e-mail
togliere <> per postarmi :
atlantide<>@
atmedia.it

...


Scusami, hai ragione... il mex che ho inviato non e' molto chiaro.
Io volevo registrare il file immagine in dimensioni piu' piccole in modo che
potesse essere di dimensioni minori possibili...
Voglio fare un programma in vb5 che prelevi un'immagine da uno scanner lo
registri in gif o jpg e quindi lo mandi via e-mail come allegato...
Il problema che non sono riuscito a risolvere sta proprio nelle dimensioni
fisiche del file e quindi mi serve un qualcosa che possa ridurmi la
dimensione effettiva dell'immagine...
Sperando di essere stato piu' chiaro ti ringrazio x il tuo aiuto...


Vuoi fare solo lo stretching o anche mantenere le proporzioni? Nel primo
caso è facile, nel secondo anche, ma non conosco la formula per calcolare
l'aspect ratio.
I primi passi sono simili per entrambi, comunque. Supponiamo di avere
un'immagine su HD (immagine.bmp ad es) di dimensioni 640x480 e di volerla
ridinsionare. La prima cosa da fare è creare un Device context vuoto e
assegnargli l'handle dell'immagine da modificare. Questo si ottiene con
l'API CreateCompatibleDC, quindi:
Dim dcImmagine As Long
dcImmagine = CreateCompatibleDC(0)
L'handle dell'immagine si ottine con la funzione LoadImage:
Dim hImmagine As Long
hImmagine = LoadImage(0, nomeFile, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION
Or LR_LOADFROMFILE)
dove al posto di nomeFile ci va la path e il nome dell'immagine da caricare.
per ottenere le dimensioni dell'immagie si dichiara un tipo BITMAP e con la
funzione GetObject si riempie:
Dim bmpInfo As BITMAP
GetObject hImmagine, Len(infoBmp), infoBmp
Per associare l'handle dell'immagine caricata in memoria si usa l'API
SelectObject:
SelectObject dcImmagine, hImmagine
e poi si distrugge l'handle per riparmiare memoria:
DeleteObject hImmagine
A questo punto abbiamo dcImmagine che è il DC dell'immagine da modificare e
le dimensioni del'immagine.
Creaiamo un secondo DC che andrà ad ospitare l'immagine modificata:
Dim dcDestinazione As Long
dcDestinazione = CreateCompatibleDC(0)
Ricapitolando:
--------------------------------------------------------------------
Dim dcImmagine As Long
Dim dcDestinazione As Long
Dim hImmagine As Long
Dim bmpInfo As BITMAP
dcImmagine = CreateCompatibleDC(0)
dcDestinazione = CreateCompatibleDC(0)
hImmagine = LoadImage(0, nomeFile, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION
Or LR_LOADFROMFILE)
GetObject hImmagine, Len(infoBmp), infoBmp
SelectObject dcImmagine, hImmagine
DeleteObject hImmagine
--------------------------------------------------------------------
Qui si dividono i due procedimenti.
1) Stretching
Si usa l'API StretchBlt.
Dim altezza As Long
Dim lunghezza As Long
' Ovviamente questi due parametri possono essere ottenuti da due TextBox
'altezza = Val(txtAltezza.Text)
'lunghezza = Val(txtLunghezza.Text)
altezza =300
lunghezza = 250
    StretchBlt dcDestinazione, 0, 0, lunghezza, altezza, dcImmagine, 0, 0,
infoBmp.bmWidth, infoBmp.bmHeight, SRCCOPY
In questo modo l'immagine viene schiacciata sia in altezza che in lunghezza,
senza mantenere le proporzioni.
2) aspect ratio
questo metodo è identico al primo, solo che altezza e lunghezza devono
rispettare una proporzione. Se me la trovi ti dico come fare.
Un'alternativa a StretchBlt è la funzione CopyImage, che permette di
cambiare le dimensioni ad una immagine senza bisogno di DC.
    CopyImage hImmagine, IMAGE_BITMAP, lunghezza, altezza, LR_COPYDELETEORG
LR_COPYRETURNORG dice alla funzione che deve distruggere la vecchia immagine
e sostituirla con quella modificata.
Con LR_COPYRETURNORG, si ottiene invece una copia esatta dell'immagine
(altezza e lunghezza vengono ignorate).
Se la tua immagine non si trova su un file, ma in una ImageBox, una
PictureBox, etc, etc basta usare la proprietà hDC del controllo.
Se non la vuoi copiare su un nuovo DC, ma su una form una picturebox, etc
basta mettere la proprietà hDC del form o picturebox a posto di
dcDestinazione.
Poi per copiarla in un file, credo che basti copiarla in una picturebox e
salvarla come bmp... oppure ti riscrivi tutto il file (leggere la
spiegazione dei vari formati).

 Or LR_LOADFROMFILE)
- Ciao Meimi, innanzi tutto complimenti per le tue conoscenze di Visual
Basic e API. Perdona la mia ignoranza, ma "l'handle dell'immagine" č
l'hDC? Questo perchč dovrei implementare qualcosa di simile:
Dim MyPic as StdPicture
MyPic = hDCToPicture(MyhDC, 0, 0, Width, Height)
SavePicture MyPic, "C:\MyFile.bmp"
ma ho le idee molto confuse. 
- Le istruzioni che hai riportato le hai tratte da qualche libro?
Ti ringrazio in anticipo Meimi e buona programmazione!
-- 
Paolo Guagliumi
_______________________________________
Casale Monferrato - Alessandria - Italy
mailto:
pguag...@dada.it
http://members.tripod.com/softwork/map


^_^ grazie

 
No, io non sono lo stesso del ridimensionamento, mi sono inserito perchč
la cosa poteva rendermi piů chiare alcune cose. Il mio obiettivo č
salvare un'immagine bmp senza usare l'istruzione savepicture che non
funziona dopo aver "animato la palette" con l'API Animatepalette, un pň
come accade con i programmi FREEWARE per la generazione dei frattali
Winfract e Fractint. Ho provato ad usare ad esempio Form1.Picture1.Image
(come molti mi hanno suggerito) invece di Form1.Picture1.Picture per
salvare l'immagine, ma niente: quando salvo l'immagine con SAVEPICTURE
Form1.Picture1.Picture "C:\mypicture.bmp" mi viene salvata l'immagine
originale e non quella ottenuta "facendo ruotare la palette".
Quindi ero alla ricerca di codice per salvare una bmp senza usare
l'istruzione SAVEPICTURE, ma č molto dura, in tutto Dejanews non ci sono
molte risposte, quindi sto cercando al limite qualche testo,
documentazione, ecc.
Grazie comunque per il prezioso aiuto, ciao.



Infatti la funziona SavePicture ti salva l'iimagine che è nella proprietà
Picture della picturebox. Anche se modifichi questa immagine con le api e
riscrivi sopra la picturebox, non te la salva.
Secondo me l'unica soluzione è ricostruire il file. I passi sono:
Aprire il file dell'iimagine originale in formato binario.
Leggere la struttura BITMAPFILEHEADER
Leggere la struttura BITMAPINFOHEADER
Leggere in un array la tavola dei colori
caricare l'immagine in un dc
Modificare l'immagine e metterla in un nuovo DC
Scrivere nel file destrinazione le struttire BITMAPFILEHEADER e
BITMAPINFOHEADER originali
Riscrivere la tavola dei colori modificata nel file
e riscrivere i byte dell'immagine.
Altre soluzioni non riesco a trovarle ;_; l'unica cosa che posso fare è
inviarti la spiegazione del formato bitmap.
Ciao

       wsprin
Ho inviato il mio progetto a 2 americani che
volevano darci un'occhiata. Spero in una loro soluzione visto che
avevano buone conoscenze sul formato BMP. Il progettino sarà freeware e
(spero di non dimenticarmi) includerò anche il tuo "nome" nei
"ringraziamenti" del programma per i preziosi e soprattutto
"professionali" suggerimenti, ti ripeto, complimenti per le tue
conoscenze!
--
_______             __      ® GENERATORE AUTOMATICO MAPPE FRATTALI
|   __ \---.-.-----.  |-----. P R O G R A M M A -  F R E E W A R E
|    __/  _  |  _  |  |  _  | IN TOP 50 FREEWARE SU  
www.zdnet.com
|___|   ___._|_____|__|_____| UTILIZZABILE CON Winfract & Fractint
|Nome:   Paolo Guagliumi    |¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|E-Mail: 
pguag...@dada.it
 | 
http://members.tripod.com/softwork/map
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯


Senza offesa, ma un programmatore in ambiente Windows che non sa cosa sia un
hWnd...
mah...
L'hWnd e' un handle (numero univoco di identificazione) di una qualsiasi
window (finestra) nel sistema operativo Windows. Nota che in Windows sono
finestre sia i form di VB che i controlli al loro interno, eccezione fatta
per label e image, che non sono controlli "windowed" (ossia non hanno hWnd).
Per quanto riguarda il salvataggio di BMP senza usare SavePicture:
- informazioni dettagliate sul formato BMP le trovi su 
www.wotsit.org
(insieme ad un sacco di altri formati grafici, volendo...)
- e' chiaro che dovresti usare le API GDI e i Device Contexts (DC)
Pero'... prima di impelagarti con API, DC etc... ti consiglierei di fare una
prova con la proprieta' hPal (handle di palette) dell'oggetto Picture. E
magari anche con la proprieta' AutoRedraw (impostata a True) del controllo
PictureBox.
--
Roal Zanazzi
z...@iol.it


*^_^*

Grazie di tutto Meimi... :-)


GetDC(HWND)
--
Roal Zanazzi
z...@iol.it


Non hai capito. Io ho il DC creato con CreateCompatibleDC, ci scrivo sopra e
voglio associare questo DC a un nuovo handle.

Un grazie sentito a tutti coloro che in qualche modo mi hanno aiutato a
risolvere il mio problema relativo al salvataggio di un'immagine BMP da
una picture-box dopo che è avvenuto un cambiamento di palette.
In particolare ringrazio un americano 
Tm4...@aol.com
 dal newsgroup
comp.lang.basic.visual.misc che mi ha suggerito di usare la clipboard.
Poi ringrazio Meimi e Roal Zanazzi per le utili informazioni e aiuti,
le...@dinet.it
 (non ricordo o non so il suo nome) per il prezioso
codice, Lorenzo Anesi per il suo interessamento.
Il seguente codice ha funzionato, in particolare uso la clipboard come
"area di comodo" della mia immagine e un'ulteriore picture-box per poi
procedere al salvataggio. Se usassi la stessa picture-box (la
Form1.picture2) ho notato che si creano degli errori nei SUCCESSIVI
richiami della DELICATA API Animatepalette (è un'API che si arrabbia
facilmente... eh, eh).
Clipboard.Clear 
Clipboard.SetData Form1.Picture2.Picture
Form2.Picture1.Picture = Clipboard.GetData(2)
Savepicture Form2.Picture1.Picture "c:\save.bmp"
Un caloroso e sentito grazie a tutti. Ciao!


 wrote in message
7h9ji0$e98$9...@fe1.cs.interbusiness.it...

Ah...pardon.
Credo non si possa fare direttamente (smentite?)
immagino che sia necessario passare il contentuto tra i due DC, via BitBlt()
--
Roal Zanazzi
z...@iol.it


E' come dici tu, l'unico modo è ricostruire il file.
Bye