2010-06-02 8 views
4

Je suis en train de rééchelonner jpeg uploadé dans asp.net.net Drawing.Graphics.FromImage() retourne image en noir en blanc

Alors je vais:

Image original = Image.FromStream(myPostedFile.InputStream); 
int w=original.Width, h=original.Height; 

using(Graphics g = Graphics.FromImage(original)) 
{ 
g.ScaleTransform(0.5f, 0.5f); ... // e.g. 
using (Bitmap done = new Bitmap(w, h, g)) 
{ 
    done.Save(Server.MapPath(saveas), ImageFormat.Jpeg); 
    //saves blank black, though with correct width and height 
} 
} 

Cela permet d'économiser un jpeg vierge noire tout fichier je le donne. Bien que si je prends flux d'images d'entrée immédiatement dans done bitmap, il ne recompresser et enregistrez-bien, comme:

Image original = Image.FromStream(myPostedFile.InputStream); 
using (Bitmap done = new Bitmap(original)) 
{ 
done.Save(Server.MapPath(saveas), ImageFormat.Jpeg); 
} 

Dois-je faire un peu de magie avec g?

màj: j'ai essayé:

Image original = Image.FromStream(fstream); 
int w=original.Width, h=original.Height; 
using(Bitmap b = new Bitmap(original)) //also tried new Bitmap(w,h) 
using (Graphics g = Graphics.FromImage(b)) 
{ 
    g.DrawImage(original, 0, 0, w, h); //also tried g.DrawImage(b, 0, 0, w, h) 
    using (Bitmap done = new Bitmap(w, h, g)) 
    { 
    done.Save(Server.MapPath(saveas), ImageFormat.Jpeg); 
    } 
} 

même histoire - noir pur de dimensions correctes

Répondre

4

Puisque vous ne l'avez pas remplir la zone avec le fond de l'image vous lisez fluxEntrée, vous ne pouvez obtenir une image vierge de cette façon . Au lieu d'utiliser la mise à l'échelle de l'image, vous pouvez utiliser Remplir l'arrière-plan dans une zone redimensionnée.

Check this out:

Image img = Image.FromFile(Server.MapPath("a.png")); 
int w = img.Width; 
int h = img.Height; 

//Create an empty bitmap with scaled size,here half 
Bitmap bmp = new Bitmap(w/2, h/2); 
//Create graphics object to draw 
Graphics g = Graphics.FromImage(bmp); 
//You can also use SmoothingMode,CompositingMode and CompositingQuality 
//of Graphics object to preserve saving options for new image.   

//Create drawing area with a rectangle 
Rectangle drect = new Rectangle(0, 0, bmp.Width, bmp.Height); 
//Draw image into your rectangle area 
g.DrawImage(img, drect); 
//Save your new image 
bmp.Save(Server.MapPath("a2.jpg"), ImageFormat.Jpeg); 

Hope this helps
Myra

+0

merci, c'est logique. Je l'ai fait un peu différemment, mais votre code était bon illustration – joox

+0

Où avez-vous ** remplir la zone avec l'arrière-plan de l'image ** exactement? –

+0

Dans la ligne de g.DrawImage (img, drect); , ce code remplit l'arrière-plan! – Myra

0

Essayez ceci: - obtenir l'image de votre flux - créer une nouvelle image de la bonne taille - Récupère l'objet Graphics du nouveau bitmap, pas celui d'origine - appelle g.DrawImage (original, 0, 0, done.Width, done.Height)

Edit: Le problème est cette section:

using (Bitmap done = new Bitmap(w, h, g)) 
    { 
    done.Save(Server.MapPath(saveas), ImageFormat.Jpeg); 
    } 

Vous créez un bitmap noir, avec la résolution spécifiée par g. En fait, vous ne créez pas de bitmap avec des données d'image provenant de g. En fait, je ne pense pas que l'objet Graphics stocke réellement des données d'image que vous pouvez vraiment transmettre, cela vous permet simplement de manipuler un objet qui stocke les données d'image.

Essayez de remplacer que par b.Save (...)

+0

'b.Save (...)' fait enregistrer les données d'image, mais ne sont pas applicables transformées. Il peut être facilement mis à l'échelle en utilisant 'b = new Bitmap (original, newWidth, newHeight)' MAIS j'ai vraiment besoin de faire une série de transformations à l'image originale, y compris le redimensionner, recadrer et faire pivoter, en essayant de le faire 'Graphics', et rend le résultat final dans un bitmap. Suis-je en train de mal comprendre l'objet 'Graphics'? – joox

+0

Quel est le bon modèle pour 1) prendre le fichier jpeg 2) appliquer séquentiellement un certain nombre de transformations 3) le sauvegarder? Cela semble simple ... – joox

+0

Je pense que c'est plus proche de dire que vous êtes des transformations d'incompréhension. Je n'ai vraiment pas traité de transformations depuis l'université, il y a environ 7 ans, donc je suis un peu rouillé. Mais j'ai fait un test simple avec une rotation, et ça a marché. L'astuce consiste à ne pas faire pivoter les données d'image, à faire pivoter le contexte graphique, puis à utiliser ce contexte pivoté pour dessiner votre image. Donc, dans mon cas, l'appel à g.RotateTransform() devait avoir lieu avant l'appel de g.DrawImage(). Comment ça va finir par vous affecter ... difficile à dire.Mais les effets cumulatifs des transformations peuvent être amusants et l'ordre des opérations peut être important. – joelt