Italian Centratura immagine dopo zoom

LucaMs

Expert
Licensed User
Longtime User
Voglio pubblicare qui la mia domanda, perché so che se lo facessi nel forum "internazionale", mi risponderebbe solo Klaus e non voglio rompergli le scatole per l'ennerima volta (si può dire che lui sia uno specialista, in questo campo).


Donq (come direbbe Taranto a Totò)...

tramite una Seekbar, consento all'utente di variare le dimensioni di una ImageView.
La Seekbar ha valore 0-100; 50 corrisponde alle dimensioni originali dell'immagine, quindi aumentandone il valore, aumentano le dimensioni della ImageView e viceServa.

Dato che però l'utente può anche spostare la ImageView sullo schermo, durante lo "zoom" dovrei anche variare le proprietà Left e Top della stessa, affinché la parte centrale visibile... rimanga centrale.

Ad esempio, se la ImageView si trova in 0,0 (posizione iniziale) ma viene ingrandita usando la Seekbar, il centro dell'immagine "scorrerà" verso il basso a destra; io vorrei che rimanesse al centro, quindi Left e Top dovranno diminuire (in una qualche proporzione rispetto all'ingrandimento).

Non allego il "progetto" sviluppato finora in quanto contiene un'immagine pesante (bella scusa, eh :D).
Questa però è la routine di "zoom", chiamata direttamente dall'evento ValueChanged della Seekbar (praticamente avrei potuto mettere il codice nell'evento stesso, ma cerco di essere pignolo e di lasciare separato il codice dalla GUI; in effetti, così facendo potrei anche chiamare la routine da codice, passandogli un Value a mio piacimento):

B4X:
Sub ZoomImage(Value As Int)

    Dim Incr As Float = (Value - 50) / 100
    Dim IncrW As Int = mSampleWidth * Incr
    Dim IncrH As Int = mSampleHeight * Incr

    ivImage.Width = mSampleWidth + IncrW
    ivImage.Height = mSampleHeight + IncrH

'    ivImage.Left = ???
'    ivImage.Top = ???

End Sub

Uhm... mi sa che non bastano le informazioni che vi ho dato.
mSampleWidth e mSampleHeight diciamo che sono le dimensioni originali della ImageView (quelle iniziali, più che altro).

Da ricordare che la ImageView viene spostata dall'utente (col ditino).

Lo Zoom, così com'è, va solo da un -50% ad un +50%; non sarebbe male portarlo da -300% a +300%, cioè riducibile a un quarto e quadruplicabile.


[Se poi arriva Klaus e, malgrado il suo tedesco, vi batte sul tempo e mi da la risposta giusta... non so come fargli un monumento :)]
 
Last edited:

LordZenzo

Well-Known Member
Licensed User
Longtime User
dunque
trovi le coordinate del centro dello schermo
dividi per due le dimensioni della imageview
sottrai dalle coordinate del centro le dimensioni trovate ed hai i valori di left e top (che possono essere tranquillamente negativi)
ossia
.left=(screen.width/2)-(im.width/2)
.top=(screen.heigth/2)-(im.height/2)
 

LucaMs

Expert
Licensed User
Longtime User
nb. Lucas da te pero' questa domanda non mel'aspettavo affatto (italiese forense)

Hai ragione ma perché... la domanda è sbagliata!

In realtà non voglio centrare la ImageView nello schermo (altrimenti userei il metodo che hai descritto, che si usa di solito per centrare ogni cosa, water escluso :p).

Mi sono spiegato male (ho delle giustificazioni ma evito, chiacchiero già fin troppo); voglio ottenere che la parte dell'immagine che ATTUALMENTE si trova al centro dello schermo, cioè prima dello zoom, rimanga al centro anche dopo la "zoommata".

Anche adesso la frase non è perfetta; più che dire "rimanga al centro", cosa non possibile, voglio che "torni" al centro, dopo la zoommata.

Mi spiego meglio con un disegnino (forse!):
upload_2016-7-8_21-5-23.png


Inizialmente, il pallino nero si trova al centro dello schermo; durante la zoommata (in aumento ed a "step", all'aumento del valore della Seekbar) il pallino si sposterà sempre più verso il basso a destra. Quando lo zoom starà al massimo (per come è fatto adesso che raggiunge soltanto il 50% in più per lato) attualmente starebbe dove vedete il pallino tratteggiato.


P.S. infatti anche il disegno è sbagliato: anche il pallino aumenta del 50% il proprio diametro, ovviamente, però si capisce ciò che intendo, dai
 

LucaMs

Expert
Licensed User
Longtime User
A quanto pare, Left e Top della ImageView devono diminuire della metà dell'incremento della "nuova" ImageView.

Se la ImageView inizialmente stesse a 0,0, essendo di dimensioni 200x200, il pallino inizialmente starebbe in 99.99 (i lati stanno da 0 a 199).
Aumentando le dimensioni del 50%, la ImageView sarà 300x300 ed il pallino starà in 149.149, quindi spostato di 50 pixel che sono la metà dell'aumento delle dimensioni della ImageView.

Scritto questo, suppongo che dovrei arrivarci, ma non adesso, è ora di spegnere 'sto coso :)
 

LordZenzo

Well-Known Member
Licensed User
Longtime User
con il sistema indicato porti il centro della view al centro dello schermo, ma aggiustando il tiro porti qualsiasi punto della view al centro dello schermo
basta conoscere lo scostamento iniziale
ossia, se lo utente sposta la view di 100 punti e poi la ingrandisce del 10% (10 punti) tu devi aggiungere o togliere la meta' di quel 10% ossia 5 punti
prova tu perche' pure io sto cotto
 

LucaMs

Expert
Licensed User
Longtime User
Ne ho provate tante, non una che funzioni :D

E' una stronzatina eppure mi scappa sotto al naso (sarà questione di dimensioni di naso, suppongo :p)

Ora raffreddo i due neuroni (doccia gelata sulla capa?), mi stacco dal PC, mi sdraio sul letto e ci penso... sono certo che in pochi minuti... mi addormenterò :p
 

klaus

Expert
Licensed User
Longtime User
I'm almost sure that this is what you expect.
B4X:
Sub ZoomImage(Value As Int)
    Dim Incr As Double = (Value + 50) / 100

    ivImage.Width = ivOriginalWidth * Incr
    ivImage.Height = ivOriginalHeight * Incr

    ivImage.Left = ivOriginalLeft - (ivImage.Width - ivOriginalWidth) / 2
    ivImage.Top = ivOriginalTop - (ivImage.Height - ivOriginalHeight) / 2
End Sub

upload_2016-7-9_18-26-16.png
upload_2016-7-9_18-27-7.png
upload_2016-7-9_18-27-57.png
 

Attachments

  • ZoomImageView.zip
    204.8 KB · Views: 347

LordZenzo

Well-Known Member
Licensed User
Longtime User
ivImage.Left = ivOriginalLeft - (ivImage.Width - ivOriginalWidth) / 2
ivImage.Top = ivOriginalTop - (ivImage.Height - ivOriginalHeight) / 2
esattamente quello che dicevo io in italiese, qui perfettamente riprodotto in b4ese
 

LucaMs

Expert
Licensed User
Longtime User
First of all many many thanks for your help, Klaus... also here :)

I'm almost sure that this is what you expect.
Unfortunately, not exactly.

I have explained bad and... in Italian!

Da ricordare che la ImageView viene spostata dall'utente (col ditino).
The user can move tha ImageView after or before zooming.

If you have a FB account, you can see there what I'm trying to obtain: the same "tool" FB provide to the user to choose his picture profile.
I'm attaching my project in which I replaced the zoom routine with yours.

What the user should be able to do is move the imageview to center a yellow rose on the screen and then zoom (in or out) on it (then he should save the yellow rose as his "avatar").

Again, I don't know how to thank you, Klaus.

-------------------------------------------

Prima di tutto, molte molte grazie per il tuo aiuto, Klaus... anche qui :)

I'm almost sure that this is what you expect.
Sfortunatamente, non esattamente.

Non mi sono spiegato bene e... in Italiano!

Da ricordare che la ImageView viene spostata dall'utente (col ditino).
L'utente può muovere l'ImageView prima o dopo lo zoom.

Se hai un account FB, puoi vedere cosa sto cercando di ottenere: lo stesso strumento che FB mette a disposizione dell'utente per scegliere l'immagine del proprio profilo.
Alllego il mio progetto nel quale ho sostituito la routine dello zoom con la tua.

Ciò che l'utente dovrebbe poter fare è muovere l'ImageView per centrare una rosa gialla nello schermo e quindi fare zoom (avanti o indietro) su essa (poi lui dovrebbe salvare la rosa gialla come proprio "avatar").


Di nuovo, non so come ringraziarti, Klaus.
 

Attachments

  • TagliaImmagine3_Klaus.zip
    90 KB · Views: 299
Last edited:

LucaMs

Expert
Licensed User
Longtime User
Sarà che programmare di notte, nel silenzio, è più facile ma che le palpebre si chiudono... il progetto che allego non funziona.
Forse è addirittura sbagliato il concetto (e lo scrivo adesso, mentre sto dormendo :D)

1) calcolo la distanza ATTUALE tra la posizione Left-Top della ImageView ed il punto centrale del "buco";
2) in base allo Zoom Attuale ed al nuovo Zoom, calcolo le nuove Left e Top
3) in base al nuovo Zoom calcolo le dimensioni della ImageView (Width e Height).

Ma qualcosa non va.

---------------------------------------------------------

In short: I tried again, in a bad way, maybe because I was programming but also sleeping at the same time :D
Maybe the project is not wrong, maybe the concept is wrong!

1) calculate the current distance between the Left-Top position of the ImageView and the central point of the "hole";
2) based on the current and the new Zoom factor, calculate the new Left and Top
3) according to the new Zoom factor calculate the new size (Width and Height).

But something is wrong.
 

Attachments

  • TagliaImmagine3Copia.zip
    92.5 KB · Views: 283

klaus

Expert
Licensed User
Longtime User
Here you are.

Improuvement suggestions:
- You may limit the zoom to the smaller side of the destination image
- You may limit the image movement to the limits of the destination image.
Wich means no white part in the destination image.

upload_2016-7-10_11-19-52.png
 

Attachments

  • TagliaImmagine4.zip
    92.6 KB · Views: 293

LucaMs

Expert
Licensed User
Longtime User
Many thanks, Klaus.

I needed also the code to save the new image, but I'm sure you're overestimating me :D; in fact, you have not modified my routine ZoomImage which... does not work.
It seems to be logical but it does not reach the goal.

You may notice this in this way:

move the image;
move the cursor (seekbar) to full scale (maximum zoom)
bring the cursor back to the center position.

Through the hole you should see the same part of the image you saw before zooming.

1) On start:
upload_2016-7-10_12-36-39.png



2) After moving:
upload_2016-7-10_12-37-9.png



3) Zoom 2x:
upload_2016-7-10_12-37-30.png



4) reset to no zoom (here you should get again the picture 2, if my routine worked :)):
upload_2016-7-10_12-37-52.png



Anyway, I thank you very much, your help is always very precious to me and even your great suggestions, Klaus.

And thanks also to follow the Italian forum ;)
 
Last edited:

klaus

Expert
Licensed User
Longtime User
I needed also the code to save the new image ...
Did you look at the code in btnSave ?
It is included.

Sorry, I hadn't understood what exactly you want to do.

Attached a modified version.

upload_2016-7-10_14-15-54.png
upload_2016-7-10_14-16-51.png
upload_2016-7-10_14-14-27.png
 

Attachments

  • TagliaImmagine5.zip
    92.5 KB · Views: 297

LucaMs

Expert
Licensed User
Longtime User
Did you look at the code in btnSave ?
It is included.

I needed also the code to save the new image, but I'm sure you're overestimating me :D; in fact, you have not modified my routine ZoomImage which... does not work.
I meant:
"I'd also need to implement this functionality (so I thank you for having written it) but the problem is my routine ZoomImage"

Thanks to your fix it now works (I do not know how it works, moreover using a lot less code; it seems a miracle!).
I have to understand that 30 (mZoomFactor = (Value + 30) / 100 ) but now the routine works.

Great, Klaus... AS ALWAYS.

Thank you.
 

klaus

Expert
Licensed User
Longtime User
I have to understand that 30 (mZoomFactor = (Value + 30) / 100 )
I wanted a zoom factor between 0.3 to 3.
The Seekbar range is set from 0 to 270.
So (Value + 30) / 100) gives as the result 0.3 for Value = 0 and 3 for a Value of 270.
 

LucaMs

Expert
Licensed User
Longtime User
Stranamante, l'immagine salvata in formato PNG sembra essere "corrotta", invece salvata come JPEG è perfetta.

Strangely, the picture saved as PNG seems to be "corrupted" but saved as JPEG it is perfect.
 
Top