C# changement de dpi d'une image téléchargée
J'ai à la fonction suivante, qui est appelé à changer la résolution d'une image. Je veux faire cela, donc téléchargé l'image avec, par exemple, 300 dpi sera modifié à 72dpi (pour le web). Cette question est liée à une autre question ici DONC où je travaille.
Je suis en création d'une méthode d'extension pour cela être capable d'utiliser cette fonction sur plus de places dans mon application, au lieu de seulement lors du téléchargement de nouveaux fichiers. (Voir ci-dessus mentionnés question)
public static byte[] SetDpiTo72(this byte[] imageToFit, string mimeType, Size newSize)
{
using (MemoryStream memoryStream = new MemoryStream(), newMemoryStream = new MemoryStream())
{
memoryStream.Write(imageToFit, 0, imageToFit.Length);
var originalImage = new Bitmap(memoryStream);
using (var canvas = Graphics.FromImage(originalImage))
{
canvas.SmoothingMode = SmoothingMode.AntiAlias;
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
canvas.DrawImage((Image)originalImage,0,0, newSize.Width, newSize.Height);
newBitmap.SetResolution(72, 72);
newBitmap.Save(newMemoryStream, ImageFunctions.GetEncoderInfo(mimeType), null);
}
return newMemoryStream.ToArray();
}
}
Mentionnés extension de la méthode est appelée dans une fonction similaire à la situation ci-dessous;
if (newSize.Width > originalImage.Width && newSize.Height > originalImage.Height)
{
newSize.Width = originalImage.Width;
newSize.Height = originalImage.Height;
uploadedFileBuffer = uploadedFileBuffer.SetDpiTo72(uploadedFile.ContentType, newSize);
return CreateFile(newSize, uploadedFile, uploadedFileBuffer);
}
L'objet bytearray à venir est le fichier dans un objet bytearray. Il a déjà à la bonne taille, mais je veux changer la résolution de 72dpi. Cependant, après un cours d'exécution et enregistrement de l'image, la résolution est toujours l'originale saisi de la résolution, qui est de 300 dpi. Comment puis-je faire cela?
MISE À JOUR APRÈS PLUSIEURS RÉPONSES:
public static byte[] SetDpiTo72(this byte[] imageToFit, string mimeType, Size newSize)
{
using (MemoryStream memoryStream = new MemoryStream(), newMemoryStream = new MemoryStream())
{
memoryStream.Write(imageToFit, 0, imageToFit.Length);
var originalImage = new Bitmap(memoryStream);
using (var canvas = Graphics.FromImage(originalImage))
{
canvas.SmoothingMode = SmoothingMode.AntiAlias;
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
canvas.DrawImage((Image)originalImage,0,0, newSize.Width, newSize.Height);
originalImage.SetResolution(72, 72);
var epQuality = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75);
var epParameters = new EncoderParameters(1);
epParameters.Param[0] = epQuality;
Image newimg = Image.FromStream(memoryStream);
//Getting an GDI+ exception after the execution of this line.
newimg.Save("C:\\test1234.jpg", ImageFunctions.GetEncoderInfo(mimeType), epParameters);
originalImage.Save("test.jpg", ImageFormat.Jpeg);
//This line give me an Argumentexception - Parameter is not valid.
//originalImage.Save(newMemoryStream, ImageFunctions.GetEncoderInfo(mimeType), epParameters);
//newMemoryStream.Close();
}
return newMemoryStream.ToArray();
}
}
La stackstrace qui vient avec l'exception est de me dire la suite;
at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
at Extensions.ByteArrayExtensions.SetDpiTo72(Byte[] imageToFit, String mimeType, Size newSize) in C:\Website\Project\Extensions\ByteArrayExtensions.cs:line 356
at CMS.Presentation.FileFunctions.CreateFullsizeImage(HttpPostedFileBase uploadedFile, Size newSize, Byte[] uploadedFileBuffer) in C:\Website\Project\CMS.Presentation\FileFunctions.cs:line 197
at CMS.Presentation.FileFunctions.CreateFile(HttpPostedFileBase uploadedFile, INodeService nodeservice, Guid userId, Node parentNode) in C:\Website\Project\CMS.Presentation\FileFunctions.cs:line 53
Dans le temps, j'ai aussi développé une autre fonction (voir ci-dessous) redimensionnement juste une image bitmap. Et cela semble fonctionner correctement. Je ne peux pas utiliser cette fonction avec mon actuel de la mise en œuvre, car il revient tout juste d'une image Bitmap. Ou dois-je changer tout de travailler avec les bitmaps?
private static Bitmap ResizeImage(Image image, int width, int height)
{
var frameCount = image.GetFrameCount(new FrameDimension(image.FrameDimensionsList[0]));
var newDimensions = ImageFunctions.GenerateImageDimensions(image.Width, image.Height, width, height);
Bitmap resizedImage;
if (frameCount > 1)
{
//we have a animated GIF
resizedImage = ResizeAnimatedGifImage(image, width, height);
}
else
{
resizedImage = (Bitmap)image.GetThumbnailImage(newDimensions.Width, newDimensions.Height, null, IntPtr.Zero);
}
resizedImage.SetResolution(72,72);
return resizedImage;
}
haha excellent! Est changé 😉
Attendre.. il l'a fait effectivement de résoudre votre problème?
Nan il n'a pas. Sera mise à jour de la question avec le code actuel..
OriginalL'auteur Rob | 2011-01-21
Vous devez vous connecter pour publier un commentaire.
Ok, je l'ai essayé que sur des fichiers sur le disque dur, mais il devrait travailler avec les flux de trop.
OriginalL'auteur Euphoric
M'a pris un moment, mais j'ai enfin trouvé le problème!
Le problème réside dans le ResizeImage fonction que j'ai utilisé. Dans le "GetThumbnailImage' pour être précis. J'ai rencontré un autre problème avec les images floues, ce qui est explicable parce que GetThumbnailImage va s'étirer jusqu'à la création de la Miniature de la taille souhaitée. Et la résolution au large de la vignette ne change jamais.
En modifiant la fonction ci-dessus pour la fonction ci-dessous, j'ai été en mesure de résoudre le problème à l'aide de Graphiques.DrawImage pour redessiner la nouvelle image avant de le rendre. Aussi la GenerateImageDimensions a été légèrement modifié. Pris ensemble, le problème a été résolu.
OriginalL'auteur Rob
Par "changer la résolution", pensez-vous réellement dire que vous voulez réduire le nombre de pixels dans l'image par 72/300? I. e. modifier une image 4000x3000 de 960x720?
Si oui, je ne peux pas voir où votre code ne fait que. Le la surcharge de DrawImage() vous utilisez fait ceci:
Qui est exactement ce qui se passe.
Essayer l'un des autres surcharges comme cette une:
par exemple:
EDIT: par les commentaires, je comprends que l'OP veut réduire la taille du fichier, sans réduire le nombre de pixels. Par conséquent, les fichiers doivent être décompressés.
J'ai emprunté un exemple de code à partir de ici:
Je viens de voir que je ne mettais pas le nécessaire taille de l'image lors de l'appel de la fonction drawimage. Vais essayer de modifier cela..
Ah, la réduction de la valeur des DPI dans le fichier, plutôt que sur le nombre total de pixels dans l'image. Désolé, pas vraiment sûr de ce que le problème est là. Gardez à l'esprit que la "résolution" de la valeur enregistrée dans le fichier image n'est pas vraiment significative du concept de l'image est stockée numériquement - ce qui est en jeu lorsque l'image est reproduite - êtes-vous sûr que vous avez réellement besoin de faire cela?
Yep absolument sûr que cela est nécessaire. La situation que j'ai est que la webapp je suis en train de travailler sur contient une bibliothèque avec des images. Chaque type d'image peut être téléchargé et sera enregistré comme blob dans la base de données avec une taille de max 7500x7500 pixels. Sur la page contenant un ou plusieurs de ces images, les fichiers sont rendus serverside avant d'être affiché à l'utilisateur. Mais le rendu sur la bonne taille et avec un 300dpi que la source est à l'origine de lourds problèmes de charge sur notre serveur. C'est pourquoi nous voulons réduire la résolution du fichier avant de l'enregistrer en tant que BLOB.
J'ai édité ma réponse avec des exemples de code.
OriginalL'auteur tomfanning
Rob, je crois que le problème avec votre code à l'enregistrement de l'image - l'image numérique de données serait certain nombre de points/pixels c'est à dire (m x n) et le paramètre de résolution au bitmap ne pas/ne devrait pas modifier le nombre de points (et donc la physique, la taille en octets de l'image). La résolution de l'information sera stockée dans l'image d'en-tête (être utilisées par les programmes en cours d'impression/édition d'images) - ce qui arrive si vous stockez la nouvelle image bitmap d'un fichier au lieu de mem flux
Vérifier dpi pour le fichier ci-dessus à partir d'un fichier -> propriétés -> résumé (avancé). Il doit être de 72 dpi.
J'ai essayé ta suggestion, mais je suis un GDI+ exception. J'ai mis à jour la question
OriginalL'auteur VinayC