Newsgroup: it.comp.lang.visual-basic
Titolo: [.NET] setdibits to device, metodi grafici e .net

Devo mostrare delle immagini di cui ho il puntatore all'area di
memoria che contiene il DIB e ho anche i bitmapinfo.
In vb6 usavo la setdibitstodevice, importando il progetto in .NET non
riesco ad usare la setdibitstodevice perchè l'oggetto PictureBox non
ha l'hdc.
Cercando su google ho trovato esempi che riguardano il metodo
drawimage ma non ho capito questo metodo come si usa, ad esempio se
scrivo nell'editor System.Drawing.Graphics il metodo drawimage non
c'è.
Lo so, ho le idee poco chiare, potreste aiutarmi a capirci qualcosa?
Grazie in anticipo

 memoria che contiene il DIB e ho anche i bitmapinfo.
Aggiungo un pezzetto di codice che ho costruito ma ahime non funziona
Magari puo' essere di ispirazione a qualcuno per aiutarmi a risolvere
sto problema
	Public Sub ArtcFrameProc(ByVal hPlayer As Integer, ByRef pBhi As
BITMAPINFOHEADER, ByRef pFrameDataSrc As Integer, ByVal pUserData As
Integer)
Dim someBitmap As Bitmap
            someBitmap = New Bitmap(frmMioform.pb1.Width,
frmMioform.pb1.Height)
            Dim someGraphics As Graphics =
Graphics.FromImage(someBitmap)
            Dim someDC As IntPtr = someGraphics.GetHdc()
            Call SetDIBitsToDevice(someDC, 0, 0, bi.bmiHeader.biWidth,
bi.bmiHeader.biHeight, 0, 0, 0, bi.bmiHeader.biHeight, pFrameDataSrc,
bi, 1)
            someGraphics.Dispose()
            frmMioform.pb1.Image = New Bitmap(someBitmap)
            someBitmap.Dispose()
            frmMioform.pb1.Refresh()
        End If
End Sub
Ma non funzia, non da errore.... ma non vedo neanche niente
HELP!


Io semplificherei un po' tutto quel malippo (non sono in grado di provare, 
però)
Call SetDIBitsToDevice(frmMioform.pb1.CreateGraphics.GetHdc, _
    0, 0, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, _
    0, 0, 0, bi.bmiHeader.biHeight, pFrameDataSrc, bi, 1)
Funziona?
Bye
Raf 


no, non funziona, il codice gira ma non vedo niente.
Non è che c'è qualche proprieta tipo la vecchia autoredraw di vb6 o
qualcosa di simile da settare nel form o nel picturebox?


Non penso, perché se invece di SetDIBitsToDevice chiami ad esempio il metodo 
FillRectangle dell'oggetto Graphics, il rettangolo appare.
Potrebbero non essere corrette le dichiarazioni delle strutture 
BITMAPINFO/BITMAPINFOHEADER, della stessa api, oppure essere un problema di 
marshaling della struttura.
Guarda questo esempio, è C#, ma non dovrebbe essere difficile tradurlo in 
VB.NET
:
http://objectmix.com/dotnet/101391-dib-bitmap-system-drawing-bitmap.html
Questo invece è in C++ (managed, mi pare)
http://bytes.com/forum/thread470432.html
Bye
Raf 

On 18 Giu, 16:05, "Rafunk" <rafunkS...@NOTHANKSlibero.it> wrote:

Le dichiarazioni eccole qua
	Structure BITMAPINFOHEADER
		Dim biSize As Integer
		Dim biWidth As Integer
		Dim biHeight As Integer
		Dim biPlanes As Short
		Dim biBitCount As Short
		Dim biCompression As Integer
		Dim biSizeImage As Integer
		Dim biXPelsPerMeter As Integer
		Dim biYPelsPerMeter As Integer
		Dim biClrUsed As Integer
		Dim biClrImportant As Integer
	End Structure
	Structure RGBQUAD
		Dim rgbBlue As Integer
		Dim rgbGreen As Integer
		Dim rgbRed As Integer
		Dim rgbReserved As Integer
	End Structure
	Structure BITMAPINFO
		Dim bmiHeader As BITMAPINFOHEADER
		Dim bmiColors As RGBQUAD
	End Structure
A proposito, per calcolare la dimensione delle strutture, in vb6 int32
e int64 quanto spazio occupano? 8 e 16 byte?

 On 18 Giu, 16:05, "Rafunk" <rafunkS...@NOTHANKSlibero.it> wrote:
preso da un dubbio atroce ho sostituito tutti i tipi dentro le
strutture con int32, ma non funge ugualmente....


No, temo che cosě non tu risolva nulla.
Dai un'occhiata in fondo a questo thread, dovrebbero esserci le 
dichiarazioni corrette:
http://forums.msdn.microsoft.com/en-US/vbgeneral/thread/c74a682b-0929-4320-80f6-179bea855e33/
Inoltre mi sembra che nella sub CreateBMP ci sia qualcosa di simile a quello 
che vorresti fare tu (copia da un array di pixels ad un oggetto Bitmap), 
forse puoi prendere spunto.
Ho la sensazione che i punti cruciali che nel tuo codice mancano siano 
LockBits, Marshal e UnlockBits...
Bye
Raf

 Raf
mmm... le strutture sono giuste...
Il fatto è che io non devo copiare da un array di byte, ma devo
mostrare un DIB di cui ho un puntatore alla locazione di memoria in
cui si trova. :-(
Il fatto del marshal mette dei dubbi anche a me, il fatto è che ho in
mano il libro del Balena, mi sono dato una letta al capitolo del
marshal e non ci ho capito granche... ne come si usa ne a cosa serve
sto marshal.....
AIUTO!

 sto marshal.....
Basta aprire il visualizzatore oggetti di VS e cercare la classe Marshal:
Provides a collection of methods for allocating unmanaged memory, copying 
unmanaged memory blocks, and converting managed to unmanaged types, as well 
as other miscellaneous methods used when interacting with unmanaged code.
In parole poverissime per trasformare dati managed (nativi .NET) in/da dati 
non managed (es. da oggetti COM, o API Win32).
HTH
Ciao
Raf 


Grande!!!
Il tuo codice mi piace molto, vorrei tanto provarlo, ma quel
Count.....? che tipo di dato deve essere? perchè pur passandogli un
integer che un int32 l'editor mi segnala errore
Value of type 'Integer' cannot be converted to '1-dimensional array of
Single'
Scusa ma non ho gran esperienza con .net, se mi risolvi


il discorso è questo, guardando in tutti e 16 gli overload della
funzione marshall.copy ho visto che almeno uno dei primi due argomenti
deve essere un array, e nel mio caso ho un puntatore e uno zero, di
conseguenza .net si infuria come una bestia....
quindi siamo punto e accapo
:-(

 :-(
al momento l'ho risolta cosi, gira senza dare errori ma continuo a non
vedere niente
 Dim myArray() As Int32
        myArray = New Int32(bi.bmiHeader.biSizeImage) {}
        Dim bm As New Bitmap(frmLogicSdk.pb1.Width,
frmLogicSdk.pb1.Height,
System.Drawing.Imaging.PixelFormat.Format24bppRgb)
        Dim bmd As System.Drawing.Imaging.BitmapData = bm.LockBits(New
Rectangle(0, 0, bm.Width, bm.Height),
System.Drawing.Imaging.ImageLockMode.ReadWrite,
System.Drawing.Imaging.PixelFormat.Format24bppRgb)
        System.Runtime.InteropServices.Marshal.Copy(pFrameDataSrc,
myArray, 0, bi.bmiHeader.biSizeImage)
        System.Runtime.InteropServices.Marshal.Copy(myArray, 0,
bmd.Scan0, bi.bmiHeader.biSizeImage)
        bm.UnlockBits(bmd)
        frmLogicSdk.pb1.Image = bm
cosa ne pensi?

> il discorso č questo, guardando in tutti e 16 gli overload della

Quella di usare un array di appoggio era proprio l'idea che stavo per 
suggerirti io, ma io avrei usato un array di byte.
Sei sicuro che bi.bmiHeader.biSizeImage corrisponda al numero di bytes 
totali dell'immagine?
La dimensione effettiva puoi ottenerla cosě:
Dim Size As Int32 = bmd.Stride * bm.Height
Quindi:
Dim pixels(Size - 1) As Byte
Marshal.Copy(pFrameDataSrc, pixels, 0, Size)
e poi
Marshal.Copy(pixels, 0, bmd.Scan0, Size)
Non ho modo di provare, fammi sapere se funge...
Ciao
Raf 

 Raf
stavolta ricevo errore qui
  System.Runtime.InteropServices.Marshal.Copy(pFrameDataSrc, pixels,
0, Size)
Tentativo di lettura o scrittura al'linterno della memoria protetta



Guarda se Size corrisponde all'effettivo numero di bytes presenti nell'area 
puntata da pFrameDataSrc, o se invece deborda, causando l'access violation.
Ciao 

 Ciao
direi che non deborda, ho provato ad inserire anche valori molto
bassi...
Ho il presentimento che questa non sia la direzione giusta.


ricapitolando...
La callback... perchè la funzione dove è posizionato questo codice è
una callback, gira senza dare errori circa una ventina di volte (ma
non si vede niente) e poi ad un certo punto avviene l'eccezione...


Non avendo modo di replicare l'ambiente operativo in cui sviluppi, mi sa che 
devo alzare bandiera bianca...
Good luck!
Raf 

 Raf
Sei stato molto gentile, grazie veramente, se ti venisse qualche idea
fammi sapere, comunque ho scritto su codeguru, nel caso ne venissi a
capo (lo spero vivamente) ti faccio sapere in che modo ho risolto.
Per il momento ciao!!