IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Probleme de conversion WMF vers PNG [Débutant]


Sujet :

C#

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 39
    Points : 30
    Points
    30
    Par défaut Probleme de conversion WMF vers PNG
    Bonjour,
    Je vous explique mon problème, j'essai de convertir un fichier WMF en PNG de cette façon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Metafile wmf = new Metafile(@"C:\imgtest.wmf");
    Bitmap bmp = new Bitmap(15000, 15000);
    Graphics g = Graphics.FromImage(bmp);
    g.DrawImage(wmf, 0, 0, 15000, 15000);
    bmp.Save(@"C:\BigOutput.png", ImageFormat.Png);
    Seulement voila, le fichier png qui en ressort est tout noir, j'ignore pourquoi.
    Quand je lui passe une taille de 10000 par 10000 ou inférieur, le PNG est générer comme il faut et affiche bien l'image contenu dans le fichier WMF, mais j'ai vraiment besoin de récupérer un fichier PNG ayant la plus grande taille possible.

    Est ce parce que je lui demande une image trop grosse par rapport a celle contenu dans mon WMF? Peut-on zoomer sur le fichier WMF avant de le passer a un bitmap, ou alors faut-il que je découpe mon fichier WMF en plusieur Bitmap de taille inférieur ( si oui, comment?)?

    Avez vous une idée?
    En vous remerciant.
    Cedric

  2. #2
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour

    Non ,non ...Pour afficher un fichier emf on doit d'abord "player" ses records ou enregistrements sur le Graphics du bmp avec un appel :
    -à la methode Graphics.EnumerateMetafileProc(Callback) et
    -Emf.PlayRecord...
    Emf.PlayRecord est une fonction unmanaged qui necessite un tableau de bytes des records.....

    code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing.Imaging;
    using System.Runtime.InteropServices;
    using System.IO;
     
    namespace WinEmfToPNG
    {
        public partial class Form1 : Form
        {
     
            private string pathFile = Directory.GetCurrentDirectory(); 
            public Form1()
            {
                InitializeComponent();
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
                DisplayImage();
     
            }
            private Metafile wmf;
            private void DisplayImage()
            {
     
                wmf = new Metafile(pathFile + @"\test.wmf");
                Graphics.EnumerateMetafileProc metafileDelegate = 
                    new Graphics.EnumerateMetafileProc(MetafileCallback);
     
                Point destPoint = new Point(0, 0);
     
                Bitmap bmp = new Bitmap(100, 100);
                Graphics g = Graphics.FromImage(bmp);
     
                g.EnumerateMetafile(wmf, destPoint, metafileDelegate);
                g.DrawImage(bmp, 0, 0, 1000, 1000);
                g.Dispose();
     
                this.pictureBox1.Image = bmp;
     
                bmp.Save(pathFile+@"\BigOutput.png", ImageFormat.Png);
     
            }
     
     
            private bool MetafileCallback(
               EmfPlusRecordType recordType,
               int flags,
               int dataSize,
               IntPtr data,
               PlayRecordCallback callbackData)
            {
                byte[] dataArray = null;
                if (data != IntPtr.Zero)
                {
                    // Copy the unmanaged record to a managed byte buffer 
                    // that can be used by PlayRecord.
                    dataArray = new byte[dataSize];
                    Marshal.Copy(data, dataArray, 0, dataSize);
                }
     
                // on "play" les records sur le graphics
                wmf.PlayRecord(recordType, flags, dataSize, dataArray);
     
                return true;
            }
     
        }
    }
    bon code.....

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 39
    Points : 30
    Points
    30
    Par défaut
    Je te remercie pour ces éclaircissements.
    Pour le moment cela ne fonctionne pas, je me retrouve avec un PNG blanc.
    J'ai oublié de préciser que je suis dans un projet WPF, pas un projet Windows Form.
    J'ignore si cela à une influence dans ce cas la.
    [Edit]
    Même dans un projet Windows Form, le rendu est blanc, que ce soit le PNG sauvegardé ou la Picturebox.
    [Edit 2]
    C'est bon, enfait au lieu de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g.DrawImage(bmp, 0, 0, 1000, 1000);
    il fallait faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g.DrawImage(wmf, 0, 0, 1000, 1000);
    C'est bien ça?
    Par contre le problème est différent, lorsque j'essai de passer une plus grosse taille a mon BMP ( 15000 par 15000) g.EnumerateMetafile me lève une ExternalException "A generic error occurred in GDI+".

  4. #4
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    rebonjour

    Oups ! En fait j'ai mal compris le besoin ...Il y a 2 operations que tu veux faire:
    -convertir au format png l'image metafile
    -la resizer et la sauvegarder...
    Sa se complique et simplifie :
    -on charge avec Image.Fromfile(metafile)....et on le sauve en png avec image.save(Image,ImageFormat)
    -on le recharge et redessine "rescalé" dans un bitmap en utilisant Graphichs.DrawImage(Image, DestRect,SourceRect, GraphicsUnit)

    code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Drawing.Imaging;
     
    namespace WinEmfToPNG
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }
            private string pathFile = Directory.GetCurrentDirectory();
            private void button1_Click(object sender, EventArgs e)
            {
                //charge wmf
                Image  wmf =Image.FromFile(pathFile + @"\test.wmf");
                //save en png
                wmf.Save(pathFile + @"\test2.png",ImageFormat.Png);
     
                //recharge
                wmf = Image.FromFile(pathFile + @"\test2.png");
                Rectangle srcRect = new Rectangle(0, 0, wmf.Width, wmf.Height);
     
                Bitmap   bmp = new Bitmap(15000, 15000);
                Graphics g = Graphics.FromImage(bmp);
     
     
                Rectangle destRect = new Rectangle(0, 0, bmp.Width, bmp.Height);
                GraphicsUnit units = GraphicsUnit.Pixel;
     
                //Dessine img sur bmp rescale suivant destRect 
                g.DrawImage(wmf, destRect, srcRect, units);
                g.Dispose();
     
     
                bmp.Save(pathFile + @"\BigOutput.png", ImageFormat.Png);
                bmp.Dispose();
     
            }
     
            private void button2_Click(object sender, EventArgs e)
            {
                Bitmap bmp = new Bitmap(pathFile + @"\BigOutput.png");
                this.pictureBox1.Image = bmp;
            }
        }
    }
    bon code.......

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 39
    Points : 30
    Points
    30
    Par défaut
    Je comprend ta méthode, mais je perd tout l’intérêt du WMF, vu que tu sauvegarde d'abord au format PNG puis tu recharge ce PNG pour l'agrandir ensuite.
    Mon but est de pouvoir agrandir tout d'abord le WMF, et ensuite le convertir. Je conserve ainsi l'avantage des images vectorielles, et je ne me retrouve pas avec une image floue.
    Une autre question, saurait tu si il est possible de decouper un WMF en plusieurs morceau?
    Etant donné que la taille réelle de mon WMF est de l'ordre de 100 000 en width et height, et qu'un bitmap ne peut être que de 32 000 par 32 000, ça serait bien de pouvoir passer plusieurs morceaux de mon WMF dans different bitmap puis de les rassembler dans un canvas ou autre.
    En te remerciant.

  6. #6
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    rebonjour

    C'est bien ca : taille du fichier wmf en pixel :100 000*100 000 ...
    Si on est RGBA 32bits 1 pixel=>4 bytes(octets)..
    Soit une taille : 100 000*100 000*4=40 000 000 000 = 40GBytes....Un monstre dirais-je numerique .
    De toute facons,l'autre aspect à gerer c'est la taille du moniteur....

    Maintenant revenons à nos moutons:
    1/ Image Floue (blurrish):
    Le code suivant illustre 2 versions d'affichage insoupconnes d' un fichier WMF dans 2 PictureBoxes le 1er "blurrish" ,le 2eme "net" et conforme à l'original wmf....
    Le 2eme Pict est resize et son image est sauve au format.png telle quelle:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    public partial class frmPicMetaFile : Form
        {
            public frmPicMetaFile()
            {
                InitializeComponent();
            }
            private string pathFile = Directory.GetCurrentDirectory();
            private void button1_Click(object sender, EventArgs e)
            {
                this.pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
                this.pictureBox1.Image = new Bitmap(pathFile + @"\DessinTest.emf");
     
                this.pictureBox2.Image = new Metafile(pathFile + @"\Test.emf");
                this.pictureBox2.SizeMode = PictureBoxSizeMode.Zoom;
                this.pictureBox2.Size = new Size(15000, 15000);
                this.pictureBox2.Image.Save(pathFile + @"\BigTest.emf", ImageFormat.Emf);
               }
        }
    Bingo l'image est nette !!!....

    2/Decouper le WMF Oui....c'est maestro Graphics.EnumerateMetafileProc avec sa fonction de Callback.....
    Elle a une surcharge qui prend un srcRect dans le metafile et un destRect(le bmp) comme dans DrawImage....
    NB: on n' as pas besoin comme deja dit dans le post precedent ,du g.DrawImage() ,cette ligne de code suffit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    g.EnumerateMetafile(wmf,srcRect, destRect ,GraphicsUnit.Pixel,
                                     metafileDelegate);
    pour instruire le Callback de dessiner dans le destRect(bmp) tous les records situes dans la zone srcRect...Car CallBack sait !!!.....que c'est sur le -g-du bitmap...merveilleux..

    Apres on save le bmp....

    code pour ce faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing.Imaging;
    using System.Runtime.InteropServices;
    using System.IO;
    using System.Drawing.Text;
    using System.Drawing.Drawing2D;
     
    namespace WinEmfToPNG
    {
        public partial class Form1 : Form
        {
     
            private string pathFile = Directory.GetCurrentDirectory(); 
            public Form1()
            {
                InitializeComponent();
            }
          // en portee class cause du playrecord 
            private Metafile wmf;
            private void button1_Click(object sender, EventArgs e)
            {
                DisplayImage();
     
            }
            private Metafile wmf;
            private void DisplayImage()
            {
     
                wmf = new Metafile(pathFile + @"\DessinTest.emf");
                Graphics.EnumerateMetafileProc metafileDelegate = 
                    new Graphics.EnumerateMetafileProc(MetafileCallback);
     
                //ESPIONNE LA TAILLE MAXIMALE DU METAFILE POUR LE TILER
                //EVENTUELLEMENT 
     
                this.Text = wmf.Height.ToString() + wmf.Width.ToString();
     
                //RECT SOURCE
                Rectangle srcRect = new Rectangle(500,500, 1500,1500);
     
                //RECT DESTINATION :  meme size
                 Rectangle destRect = new Rectangle(0, 0,srcRect.Width,srcRect.Height );
     
               // BMP: meme size que  destRect
               Bitmap bmp  = new Bitmap(destRect.Width, destRect.Height);
               Graphics grBmp = Graphics.FromImage(bmp);
               grBmp.CompositingQuality=CompositingQuality.HighQuality;
     
                //DESSIN: encore une fois pas besoin de g.DrawImage !!!!..           
     
               grBmp.EnumerateMetafile(wmf, destRect, srcRect, GraphicsUnit.Pixel,
                                                 metafileDelegate);
               grBmp.Dispose();
     
     
               bmp.Save(pathFile + @"\part.png", ImageFormat.Png);
     
               this.pictureBox1.Image = bmp;
            }
     
     
            private bool MetafileCallback(
               EmfPlusRecordType recordType,
               int flags,
               int dataSize,
               IntPtr data,
               PlayRecordCallback callbackData)
            {
                byte[] dataArray = null;
                if (data != IntPtr.Zero)
                {
                    // Copy the unmanaged record to a managed byte buffer 
                    // that can be used by PlayRecord.
                    dataArray = new byte[dataSize];
                    Marshal.Copy(data, dataArray, 0, dataSize);
                }
     
                // "play"  records sur le graphics
                wmf.PlayRecord(recordType, flags, dataSize, dataArray);
     
                return true;
            }
     
        }
    }
    bon code......

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 39
    Points : 30
    Points
    30
    Par défaut
    Respect.
    Je te remercie, cela correspond exactement à ce dont j'avais besoin.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. DLL conversion pdf vers image (Jpeg ou png)
    Par mickmix69 dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 03/12/2012, 13h08
  2. Conversion BMP vers JPG ou PNG
    Par toine92 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 31/03/2010, 11h25
  3. Conversion TIFF vers PNG ou JPG à la volée
    Par yellowsub122 dans le forum ASP.NET
    Réponses: 4
    Dernier message: 08/03/2010, 22h00
  4. Conversion Unix vers DOS...
    Par nicosfly dans le forum Langage
    Réponses: 4
    Dernier message: 23/06/2008, 17h53
  5. Réponses: 7
    Dernier message: 24/08/2006, 08h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo