Oppure

Loading
05/06/10 8:44
Lorenzo L
Salve a tutti, sono un nuovo utente ma consulto questo interessantissimo sito da tempo.

Ho un problema che probabilmente si dimostrerà essere una stupidata...

In pratica devo sovrapporre un logo su una immagine, mantenendo i bordi rendendo trasparenti alcune parti del logo stesso. Quindi in modo abbastanza efficace ho usato l'API TransparentBlt. Però quando devo salvare l'immagine nella picture modificata, non viene inserito il logo. Questo invece succedeva se usavo il metodo PaintPicture, ma avevo l'inconveniente che non c'era la trasparenza...

Dove sbaglio?

'Ci sono solo due Picturebox. Picturebox1 è un'immagine con il logo il cui colore bianco deve essere reso trasparente. La Picturebox2 contiene lo sfondo.
Private Declare Function TransparentBlt Lib "msimg32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal crTransparent As Long) As Boolean
Private Sub Form_Load()
    Picture1.ScaleMode = vbPixels
    Picture2.ScaleMode = vbPixels
    Picture1.AutoSize = True
End Sub

Private Sub Picture2_Paint()
    DoEvents
    TransparentBlt Picture2.hdc, 0, 0, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture1.hdc, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, vbWhite
    SavePicture Picture2.Image, "c:\prova.bmp"
End Sub


Grazie a tutti!!!
Siete grandi!
aaa
05/06/10 11:28
Alfonso
Il risultato della tua routine è solo virtuale. Quello che vedi è memorizzato nella zona usata per il display del monitor.
L'unica maniera per poter salvare il risultato è operare una cattura della porzione di schermo che inquadra la PictureBox2.
Oppure, cambiando metodo, usare la funzione BitBlt e qualche maschera.
aaa
05/06/10 12:32
Lorenzo L
Salve,

grazie mille della pronta risposta. Immaginavo, a forza di tentativi, che l'immagine fosse solo virtuale. Ho provato con il metodo bitblt ma non cambia nulla.


'Ci sono solo due Picturebox. Picturebox1 è un'immagine con il logo il cui colore bianco deve essere reso trasparente. La Picturebox2 contiene lo sfondo.
Private Declare Function TransparentBlt Lib "msimg32.dll" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal crTransparent As Long) As Boolean
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

Private Sub Form_Load()
    Picture1.ScaleMode = vbPixels
    Picture2.ScaleMode = vbPixels
    Picture1.AutoSize = True
End Sub

Private Sub Picture2_Paint()
    DoEvents
    TransparentBlt Picture2.hdc, 0, 0, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture1.hdc, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, vbWhite
    BitBlt Picture3.hdc, 0, 0, Picture2.Width, Picture2.Height, Picture2.hdc, 0, 0, vbSrcCopy
    SavePicture Picture3.Image, "c:\fotoelogo.bmp"
    
End Sub


In ogni caso, esistono altre vie con VB6 per inserire un immagine sopra ad un'altra con relativa trasparenza (quindi senza usare paintimage) e soprattutto salvare il risultato?
aaa
05/06/10 12:52
Alfonso
Questo è un piccolo esempio. Bisogna solo crearsi una bitmap che funga da maschera.
aaa
05/06/10 13:44
Lorenzo L
Grazie Alfonso.

Il programma che hai gentilmente postato lo studiato per bene, però non mi sembra abbastanza flessibile. Infatti devo sempre avere due immagini (logo + mask) e lo sfondo. La mask non è tanto facile da fare se ho ad'esempio un titolo sotto il logo.

Ultima modifica effettuata da Lorenzo L 05/06/10 13:46
aaa
05/06/10 15:04
Alfonso
Puoi sempre crearti al volo la maschera. Nel caso il colore da rendere trasparente sia il bianco:

Private Function CreaMaschera()
  Dim x As Integer, y As Integer
  Mask.Picture = PictureBox1.Picture
  For x = 0 To PictureBox1.ScaleWidth
    For y = 0 To PictureBox1.ScaleHeight
       If Mask.Point(x, y) <> vbWhite Then
         Mask.PSet (x, y), vbBlack
       End If
    Next
  Next
End Function
aaa
06/06/10 11:46
Lorenzo L
Grazie mille!
Così posso superare le difficoltà che avevo trovato. Visto che comunque nel web ho trovato altri utenti che si facevano la mia domanda, se riesco faccio un piccolo programma-riassuntivo del prezioso codice postato da Alfonso. :k:
aaa