Extrait une image d'un film pour l'afficher dans une picturebox

astragoth66 Messages postés 31 Date d'inscription lundi 6 juin 2005 Statut Membre Dernière intervention 2 octobre 2005 - 13 juin 2005 à 14:08
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 - 28 juin 2005 à 02:04
Bonjour,

Voila j'essaie
d'extraire une image d'un films pour ensuite faire du traitement
d'image dessus, mais j'aimerai afficher image par image dans ma
picturebox.

J'utilise C#

J'ai une classe qui s'appelle
AviReader, qui me permet d'ouvrir mon film et faire ce que je ve avec,
et voici mon code qui devrai normalement extraire l'image à la position
"position" (paramétre d'entre de lafonction) et cet fonction doit me
retourner un object de type Bitmap pour l'afficher dans ma picturebox.



public Bitmap ExtraitBmpAvi(int position)

{

if(position > countFrames)

{

throw new Exception("Invalid frame position");

}



//Decompress the frame and return a pointer to the DIB

int pDib =
Avi.AVIStreamGetFrame(getFrameObject, firstFrame + position);

//Copy the bitmap header into a managed struct

Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER();

bih =
(Avi.BITMAPINFOHEADER)Marshal.PtrToStructure(new IntPtr(pDib),
bih.GetType());



/*if(bih.biBitCount < 24){


throw new Exception("Not enough colors! DIB color
depth is less than 24 bit.");

}else */

if(bih.biSizeImage < 1)

{


throw new Exception("Exception in AVIStreamGetFrame:
Not bitmap decompressed.");

}



//Copy the image

byte[] bitmapData = new byte[bih.biSizeImage];

int address = pDib + Marshal.SizeOf(bih);

for(int offset=0; offset<bitmapData.Length; offset++)

{


bitmapData[offset] = Marshal.ReadByte(new
IntPtr(address));

address++;

}

MemoryStream mm = new MemoryStream(bitmapData);

Bitmap bmp = new Bitmap(Image.FromStream(mm));

mm.Close();

return bmp;

}



Alors tout simplement ca plante, je pense que c'est au niveau de la mémoire, mais la, j'en ai pas la moindre idée.

merci pour toute l'aide que vous pouvez m'apporter

@pluche

@str@goth

35 réponses

astragoth66 Messages postés 31 Date d'inscription lundi 6 juin 2005 Statut Membre Dernière intervention 2 octobre 2005
13 juin 2005 à 20:42
public Bitmap ExtraitBmpAvi(int position)

{

if(position > countFrames)

{

throw new Exception("Invalid frame position");

}



//Decompress the frame and return a pointer to the DIB

int pDib =
Avi.AVIStreamGetFrame(getFrameObject, firstFrame + position);

//Copy the bitmap header into a managed struct

Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER();

bih =
(Avi.BITMAPINFOHEADER)Marshal.PtrToStructure(new IntPtr(pDib),
bih.GetType());



/*if(bih.biBitCount < 24){


throw new Exception("Not enough colors! DIB color
depth is less than 24 bit.");

}else */

if(bih.biSizeImage < 1)

{


throw new Exception("Exception in AVIStreamGetFrame:
Not bitmap decompressed.");

}



//Copy the image

byte[] bitmapData = new byte[bih.biSizeImage];

int address = pDib + Marshal.SizeOf(bih);

for(int offset=0; offsetMemoryStream mm = new MemoryStream();



//Write bitmap info

mm.Write(bitmapInfo,0,bitmapInfo.Length);



//Write bitmap data

mm.Write(bitmapData,bitmapInfo.Length,bitmapData.Length);

Bitmap bmp = (Bitmap)Image.FromStream(mm);



mm.Close();



return bmp;

}



Voila j'ai fait ce que tu m'a dit, mais ca plante toujours sur le FromStream avec la meme erreurs !!!!

HELP !!!!!!!!!!!!!!!
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
13 juin 2005 à 20:47
Sebmafate, j'avais prevenu c'etait juste une idee comme ca.. c'etait meme une question.. Mais effectivement je viens de voir pleins d'exemples ou ca fonctionne tres bien.. Perso, je prefere utiliser le constructeur que j'ai indique plus haut..
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
13 juin 2005 à 20:57
Ok, voici comment je ferais.

int currPos = 0;
mm.Write(bfh.bfSize, currPos, Marshal.SizeOf(bfh.bfSize));
currPos += Marshal.SizeOf(bfh.bfSize);
mm.Write (bfh.bfReserved1, currPos, Marshal.SizeOf(bfh.bfReserved1));
currPos += Marshal.SizeOf(bfh.bfReserved1);
mm.Write (bfh.bfReserved2, currPos, Marshal.SizeOf(bfh.bfReserved2));
currPos += Marshal.SizeOf(bfh.bfReserved2);
mm.Write(bfh.bfOffBits, currPos, Marshal.SizeOf(bfh.bfOffBits));
currPos += Marshal.SizeOf(bfh.bfOffBits);
mm.Write(bitmapInfo, currPos, bitmapInfo.Length);
currPos += bitmapInfo.Length;
mm.Write(bitmapData, currPos, bitmapData);

Bitmap bitmap = (Bitmap)Bitmap.FromStream(mm);

mm.Close();

Voila, je n'ai pas testé... mais c'est à toi d'essayer.

Sébastien FERRAND

Blog : http://blogs.developpeur.org/sebmafate
</FO< body>
0
astragoth66 Messages postés 31 Date d'inscription lundi 6 juin 2005 Statut Membre Dernière intervention 2 octobre 2005
13 juin 2005 à 21:26
petit soucis:

bfh.bfSize et bfh.bfOffBits c'est de type int

bfh.bfReserved1 et bfh.bfReserved2 c'est de type short

or write attend des variable de type byte[]

euh je vais être lourd mais je fait comment ???
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
astragoth66 Messages postés 31 Date d'inscription lundi 6 juin 2005 Statut Membre Dernière intervention 2 octobre 2005
13 juin 2005 à 21:38
en faite c bon j'ai trouvé

voila le code:



int currPos = 0;


mm.Write(BitConverter.GetBytes(bfh.bfSize), currPos,
Marshal.SizeOf(bfh.bfSize));

currPos += Marshal.SizeOf(bfh.bfSize);


mm.Write(BitConverter.GetBytes(bfh.bfReserved1), currPos,
Marshal.SizeOf(bfh.bfReserved1));

currPos += Marshal.SizeOf(bfh.bfReserved1);

mm.Write
(BitConverter.GetBytes(bfh.bfReserved2), currPos,
Marshal.SizeOf(bfh.bfReserved2));

currPos += Marshal.SizeOf(bfh.bfReserved2);


mm.Write(BitConverter.GetBytes(bfh.bfOffBits), currPos,
Marshal.SizeOf(bfh.bfOffBits));

currPos += Marshal.SizeOf(bfh.bfOffBits);

mm.Write(bitmapInfo, currPos, bitmapInfo.Length);

currPos += bitmapInfo.Length;

mm.Write(bitmapData, currPos, bitmapData.Length);



Bitmap bmp = (Bitmap)Bitmap.FromStream(mm);



Mais ca plante a la ligne en gras

j'ai peut etre fait une connerie ???
0
astragoth66 Messages postés 31 Date d'inscription lundi 6 juin 2005 Statut Membre Dernière intervention 2 octobre 2005
14 juin 2005 à 09:58
J'arrive toujours pas a faire fonctionner ce code, si quelqu'un peux m'aider, ca pourrai etre cool



merci bcp
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
14 juin 2005 à 10:05
Une solution de secours.

Etant que le code qui te sert d'exemple fonctionne, pourquoi ne pas le réutiliser ?
C'est à dire, utiliser un FileStream plutot qu'un MemoryStream ? Il te suffira de supprimer le fichier créé sur le disque à la fin de ta procédure.


<HR>
Sébastien FERRAND

Blog : http://blogs.developpeur.org/sebmafate
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
14 juin 2005 à 17:42
Si ta lib AVI te permet de recuperer le BITMAPINFOHEADER d'une frame et le scan0 ou un tableau de bytes des pixels de ton bitmap, pourquoi ne pas essayer ce constructeur :

Bitmap( Int32, Int32, Int32, PixelFormat, IntPtr )
0
astragoth66 Messages postés 31 Date d'inscription lundi 6 juin 2005 Statut Membre Dernière intervention 2 octobre 2005
14 juin 2005 à 18:04
c'est ce que j'ai essaier, mais ca plante, peut etre que j'ai mal codé

voila mon code :

Bitmap bmp = new Bitmap(bih.biWidth,bih.biHeight,bih.biSize,PixelFormat.Format24bppRgb,ptr);





sauf que l'image afficher déconne méchant, meme en changeant le format des pixels ....

mon image est un ensemble de ligne oblike, toute dans le meme sens, sur un joli fond noir

donc si tu as une idée fait la moi savoir

merci
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
14 juin 2005 à 18:24
Vi, mais moi je ne le sais pas que tu as essayé, si tu ne le dis pas : )

Tu es sur d'avoir bien calculé le scan0 ? Attention aux differents headers de tailles differentes.. Attention aux bitmaps inversés.. Voir la MSDN.. Tu peux tester en avancant d'un byte a chaque fois ton scan0 pour comprendre la structure de ton bitmap.
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
14 juin 2005 à 18:36
J'avais pas vu, y'a un probleme avec le stride..

Extrait MSDN:

Cette valeur est la largeur d'une seule ligne de pixels (une ligne de numérisation), arrondie à une limite de quatre octets. La largeur de numérisation est toujours supérieure ou égale à la largeur réelle en pixels. Si la largeur de numérisation est positive, la bitmap est de haut en bas. Si la largeur de numérisation est négative, la bitmap est de bas en haut.
0
astragoth66 Messages postés 31 Date d'inscription lundi 6 juin 2005 Statut Membre Dernière intervention 2 octobre 2005
15 juin 2005 à 11:19
Voila mon code, j'essayer de trouver ce que vau stride, sauf que je ne
trouve rien, et la définition que tu m'a donné, le mec il a fumer je
sias pas quoi avant de l'ecrire, car jecomprend que dalle.

public Bitmap ExtraitBmpAvi(int position)

{

if(position > countFrames)

{

throw new Exception("Invalid frame position");

}



//Decompress the frame and return a pointer to the DIB

int pDib =
Avi.AVIStreamGetFrame(getFrameObject, firstFrame + position);

//Copy the bitmap header into a managed struct

Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER();

bih =
(Avi.BITMAPINFOHEADER)Marshal.PtrToStructure(new IntPtr(pDib),
bih.GetType());

/*if(bih.biBitCount < 24){


throw new Exception("Not enough colors! DIB color
depth is less than 24 bit.");

}else */

if(bih.biSizeImage < 1)

{


throw new Exception("Exception in AVIStreamGetFrame:
Not bitmap decompressed.");

}



//Copy the image

byte[] bitmapData = new byte[bih.biSizeImage];

int address = pDib + Marshal.SizeOf(bih);

for(int offset=0; offset<bitmapData.Length; offset++)

{


bitmapData[offset] = Marshal.ReadByte(new
IntPtr(address));

address++;

}





//Copy bitmap info

byte[] bitmapInfo = new byte[Marshal.SizeOf(bih)];

IntPtr ptr;

ptr = Marshal.AllocHGlobal(bitmapInfo.Length);

Marshal.StructureToPtr(bih, ptr, false);

address = ptr.ToInt32();

for(int offset=0; offset<bitmapInfo.Length; offset++)

{


bitmapInfo[offset] = Marshal.ReadByte(new
IntPtr(address));

address++;

}



//Create file header

Avi.BITMAPFILEHEADER bfh = new Avi.BITMAPFILEHEADER();

bfh.bfType = Avi.BMP_MAGIC_COOKIE;

bfh.bfSize =
(Int32)(55 + bih.biSizeImage); //size of file as written to disk

bfh.bfReserved1 = 0;

bfh.bfReserved2 = 0;

bfh.bfOffBits = Marshal.SizeOf(bih) + Marshal.SizeOf(bfh);



Bitmap bmp =
new
Bitmap(bih.biWidth,bih.biHeight,4*(bih.biWidth/bih.biHeight),PixelFormat.Format24bppRgb,ptr);

return bmp;

}

Avec ce code j'obtient une image bizard, fond noir, avec quelque ligne oblique multicolore.

Donc si tu voit d'ou vient mon probléme ca pourrai etre cool

merci d'avance
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
15 juin 2005 à 17:33
Salut, moui c'est vrai que la definition de la MSDN est pas tres clair : ) J'ai deja utilisé cette fonction et je me souviens que j'avais galeré avec ce "stride", mais impossible de retrouver mon code.. Mais là tu commences à avoir une image qui ressemble à l'originale, non ? En fait pour le stride "je crois" qu'il suffit de mettre la largeur en pixel de ton image, et seulement si ton image à une largeur qui n'est pas un multiple de 4 alors tu arrondies au multiple de 4 superieur.. Si ton image est a l'envers alors ca veut dire que c'est un bitmap inversé.. Si tes lignes sont visibles mais decalées ou cassées ca veut dire que tu n'as pas le bon scan0.. faut avancer byte par byte..
0
astragoth66 Messages postés 31 Date d'inscription lundi 6 juin 2005 Statut Membre Dernière intervention 2 octobre 2005
17 juin 2005 à 10:13
Salut

non je n'ai pas l'image qui s'affiche, ou alors je peux pas voir si
c'est l'image, car les lignes oblike ont une epaisseur d'un ou 2 pixel
.....

si tu veux je peux t'envoyer l'image que ca me donne, histoire que tu contaste nettement mieux l'image obtenue.



j'ai essayer de mettre la largeur de l'image en pixel, mais c'est toujours pas bon.
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
28 juin 2005 à 02:04
Rhaaa.. j'ai compris le stride, c'est la largeur de ton image multiplié par le nombre de bytes ( pas bits ) par exemple pour une image de 256*256*24 ( 24 bits soit 3 bytes ) ca donne un stride de 256 * 3 = 768.. autre exemple une image de 256*256*32 ( 32 bits soit 4 bytes ) donne un stride 256*4 = 1024.. Pour les images qui n'ont pas des dimensions multiples de 4 la faut arrondir au multiple de 4 supérieur..
0
Rejoignez-nous