Meilleur auteur de réponses
Conversion WebControls.Image en Drawing.Image

Question
-
Bonjour, dans une application web que je developpe, je génère une image à la volé dans une page web, que je passe à ImageUrl d'un objet WebControls.Image présent dans ma page Default.aspx.
Dans la même page, j'ai un bouton VersPDF qui doit prendre le contenu de mon WebControls.Image et générer un fichier PDF, le problème qui se pose est que la méthode ToPDF que j'utilise peut avoir en paramètres soit un objet Drawing.Image ou un string contenant le chemin physique de l'image (à ignorer puisque on ne veux pas enregistrer l'image dans le serveur, ni chez le client).
Ce qui m'a poussé à ecrire le code 2 fois, dans la 1ere page dans le Form_Load et dans la 2eme page dans VersPDF_Click:
Form_Load(object sender, EventArgs e)
{
Image monImage;
// Connexion à la base de données
Connexion();
DataSet myDataSet = new DataSet("monDataSet");
// Declaration du DataAdapter et du DataTable
OleDbDataAdapter myAdapter;
string Requete = "SELECT Code, Tx1 FROM Table3";
myAdapter = new OleDbDataAdapter(Requete, myConnection);
myAdapter.Fill(myDataSet, "Table3");
// Génération de l'image contenant un graphique de type BarChart
BarChart bc = new BarChart(myDataSet, "mon BarChart", "Période", "Taux", 600, 500,
chemin, new Pen(Brushes.Gray), new Font("Verdana", 8), Brushes.Black, Brushes.White);
monImage = bc.GenerateChart();
monImage.Save(Response.OutputStream, ImageFormat.Jpeg);
// Libération des ressources utilisées par bc
bc.Dispose();
// Déconnexion de la base de données
Deconnexion();
}
le même code a été repris dans le VersPDF_Click
protected void Button1_Click(object sender, EventArgs e)
{
string Requete = "SELECT Code, Tx1 FROM Table3";
myAdapter = new OleDbDataAdapter(Requete, myConnection);
myAdapter.Fill(myDataSet, "Table3");
BarChart bc = new BarChart(myDataSet, "mon BarChart", "Période", "Taux", 600, 500,
chemin, new Pen(Brushes.Gray), new Font("Verdana", 8), Brushes.Black, Brushes.White);
monImage = bc.GenerateChart();
PDF myPdf = new PDF("Titre", "Auteur");
myPdf.ToPdf(monImage, path + "D:\\Webform.pdf");
}
pour éviter à retaper le code 2 fois, y aurait il un moyen de convertir un objet WebControls.Image en Drawing.Image, n'importe quelle suggestion sera la bienvenue
merci d'avance
Réponses
-
Bonjour,
La classe System.Drawing.Image s'appuyant sur GDI+, il n'est pas recommandé de mettre en cache l'objet image généré par la méthode GenerateChart.
A mon avis la seule solution qui tienne la route est de faire une sérialization binaire de l'objet image dans un tableau d'octets, puis de mettre en cache ce tableau d'octets soit dans l'objet Session soit dans l'objet Cache.
Le code suivant devrait vous montrer comment faire :
Extrait de codeprivate System.Drawing.Image GetImageFromDataSource()
{System.Drawing.Image myImage = System.Drawing.Image.FromFile(@"c:\temp\test.bmp");
// On met l'image en cache
// On instancie un sérialiseur binaire
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter mySerializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
// On effectue la sérialisationSystem.IO.MemoryStream myStream = new System.IO.MemoryStream();
mySerializer.Serialize(myStream,myImage);
//On génère un tableau de bytes à partir du stream
byte[] myByteArray = myStream.ToArray();// on finalise le stream;
myStream.Close();
myStream.Dispose();
myStream = null;// on met l'image en cache
Session["myImage"] = myByteArray;
return myImage;
}private System.Drawing.Image GetImageFromCache()
{
// on tente de récupérer l'image du cache
System.Object myObject = Session["myImage"];
if (myObject == null)
{
return GetImageFromDataSource();
}// Ok, l'image ets bien en cache : il faut désérialiser
byte[] myImageAsByteArray = (byte[])myObject;
System.IO.MemoryStream myStream = new System.IO.MemoryStream();
myStream.Write(myImageAsByteArray, 0, myImageAsByteArray.Length);
myStream.Position = 0;System.Runtime.Serialization.Formatters.Binary.BinaryFormatter mySerializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
System.Drawing.Image myImage = (System.Drawing.Image) mySerializer.Deserialize(myStream);
myStream.Close();
myStream.Dispose();
myStream = null;return myImage;
}protected void Page_Load(object sender, EventArgs e)
{System.Drawing.Image myImage = GetImageFromCache();
// code de test, juste pour vérifier que la désérialisation a fonctionnée
myImage.Save(@"c:\temp\titi.bmp");
myImage.Save(Response.OutputStream, ImageFormat.Jpeg);
myImage.Dispose();}
Toutes les réponses
-
Bonjour,
La classe System.Drawing.Image s'appuyant sur GDI+, il n'est pas recommandé de mettre en cache l'objet image généré par la méthode GenerateChart.
A mon avis la seule solution qui tienne la route est de faire une sérialization binaire de l'objet image dans un tableau d'octets, puis de mettre en cache ce tableau d'octets soit dans l'objet Session soit dans l'objet Cache.
Le code suivant devrait vous montrer comment faire :
Extrait de codeprivate System.Drawing.Image GetImageFromDataSource()
{System.Drawing.Image myImage = System.Drawing.Image.FromFile(@"c:\temp\test.bmp");
// On met l'image en cache
// On instancie un sérialiseur binaire
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter mySerializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
// On effectue la sérialisationSystem.IO.MemoryStream myStream = new System.IO.MemoryStream();
mySerializer.Serialize(myStream,myImage);
//On génère un tableau de bytes à partir du stream
byte[] myByteArray = myStream.ToArray();// on finalise le stream;
myStream.Close();
myStream.Dispose();
myStream = null;// on met l'image en cache
Session["myImage"] = myByteArray;
return myImage;
}private System.Drawing.Image GetImageFromCache()
{
// on tente de récupérer l'image du cache
System.Object myObject = Session["myImage"];
if (myObject == null)
{
return GetImageFromDataSource();
}// Ok, l'image ets bien en cache : il faut désérialiser
byte[] myImageAsByteArray = (byte[])myObject;
System.IO.MemoryStream myStream = new System.IO.MemoryStream();
myStream.Write(myImageAsByteArray, 0, myImageAsByteArray.Length);
myStream.Position = 0;System.Runtime.Serialization.Formatters.Binary.BinaryFormatter mySerializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
System.Drawing.Image myImage = (System.Drawing.Image) mySerializer.Deserialize(myStream);
myStream.Close();
myStream.Dispose();
myStream = null;return myImage;
}protected void Page_Load(object sender, EventArgs e)
{System.Drawing.Image myImage = GetImageFromCache();
// code de test, juste pour vérifier que la désérialisation a fonctionnée
myImage.Save(@"c:\temp\titi.bmp");
myImage.Save(Response.OutputStream, ImageFormat.Jpeg);
myImage.Dispose();}
-