Je développe une application Web ASP.NET 3.5 dans laquelle je permets à mes utilisateurs de télécharger des images jpeg, gif, bmp ou png. Si les dimensions de l'image téléchargées sont supérieures à 103 x 32, je veux redimensionner l'image téléchargée à 103 x 32. J'ai lu des articles de blog et des articles, et j'ai aussi essayé quelques exemples de code, mais rien ne semble fonctionner. Est-ce que quelqu'un a réussi à faire cela?Redimensionner une image dans asp.net sans perdre la qualité de l'image
Répondre
J'ai eu le même problème un certain temps et a traité de cette façon:
private Image RezizeImage(Image img, int maxWidth, int maxHeight)
{
if(img.Height < maxHeight && img.Width < maxWidth) return img;
using (img)
{
Double xRatio = (double)img.Width/maxWidth;
Double yRatio = (double)img.Height/maxHeight;
Double ratio = Math.Max(xRatio, yRatio);
int nnx = (int)Math.Floor(img.Width/ratio);
int nny = (int)Math.Floor(img.Height/ratio);
Bitmap cpy = new Bitmap(nnx, nny, PixelFormat.Format32bppArgb);
using (Graphics gr = Graphics.FromImage(cpy))
{
gr.Clear(Color.Transparent);
// This is said to give best quality when resizing images
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.DrawImage(img,
new Rectangle(0, 0, nnx, nny),
new Rectangle(0, 0, img.Width, img.Height),
GraphicsUnit.Pixel);
}
return cpy;
}
}
private MemoryStream BytearrayToStream(byte[] arr)
{
return new MemoryStream(arr, 0, arr.Length);
}
private void HandleImageUpload(byte[] binaryImage)
{
Image img = RezizeImage(Image.FromStream(BytearrayToStream(binaryImage)), 103, 32);
img.Save("IMAGELOCATION.png", System.Drawing.Imaging.ImageFormat.Gif);
}
Je viens de lire que c'était la façon d'obtenir la plus haute qualité.
+1 Nice : "Double ratio = Math.Max (xRatio, yRatio);" – Joop
Dans une nouvelle version, je prends également en compte que je ne vais pas étirer les images, mais cela devrait être assez facile à travailler :-P (indice: 'ration = Math.Min (ration, 1.0);') – Alxandr
Bien , il y a [un peu plus de paramètres qui aideront] (http://nathanaeljones.com/163/20-image-resizing-pitfalls/), tels que le décalage de pixels. –
Je l'ai fait avec succès en créant une image bitmap de l'image, puis en redimensionnant l'image bitmap ... Je ne sais pas si c'est la meilleure ou la plus efficace de faire cela, mais ça marche pour moi.
Dans mon cas, j'avais besoin de couper la hauteur et la largeur de l'image de moitié.
Voici ce que j'ai fait.
private Image getImageFromBytes(byte[] myByteArray)
{
System.IO.MemoryStream newImageStream = new System.IO.MemoryStream(myByteArray, 0, myByteArray.Length);
Image image = Image.FromStream(newImageStream, true);
Bitmap resized = new Bitmap(image, image.Width/2, image.Height/2);
image.Dispose();
newImageStream.Dispose();
return resized;
}
Ceci est le code que j'utilise. Il prend en charge la rotation et règle également la résolution de l'image sur les normes JPEG de 72dpi @ couleur 24 bits (par défaut GDI + enregistre les images à 96dpi @ couleur 32 bits). Il corrige également le problème de bordure noire/grise que certaines personnes rencontrent lors du redimensionnement d'images.
/// <summary>
/// Resizes and rotates an image, keeping the original aspect ratio. Does not dispose the original
/// Image instance.
/// </summary>
/// <param name="image">Image instance</param>
/// <param name="width">desired width</param>
/// <param name="height">desired height</param>
/// <param name="rotateFlipType">desired RotateFlipType</param>
/// <returns>new resized/rotated Image instance</returns>
public static Image Resize(Image image, int width, int height, RotateFlipType rotateFlipType)
{
// clone the Image instance, since we don't want to resize the original Image instance
var rotatedImage = image.Clone() as Image;
rotatedImage.RotateFlip(rotateFlipType);
var newSize = CalculateResizedDimensions(rotatedImage, width, height);
var resizedImage = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppArgb);
resizedImage.SetResolution(72, 72);
using (var graphics = Graphics.FromImage(resizedImage))
{
// set parameters to create a high-quality thumbnail
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
// use an image attribute in order to remove the black/gray border around image after resize
// (most obvious on white images), see this post for more information:
// http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx
using (var attribute = new ImageAttributes())
{
attribute.SetWrapMode(WrapMode.TileFlipXY);
// draws the resized image to the bitmap
graphics.DrawImage(rotatedImage, new Rectangle(new Point(0, 0), newSize), 0, 0, rotatedImage.Width, rotatedImage.Height, GraphicsUnit.Pixel, attribute);
}
}
return resizedImage;
}
/// <summary>
/// Calculates resized dimensions for an image, preserving the aspect ratio.
/// </summary>
/// <param name="image">Image instance</param>
/// <param name="desiredWidth">desired width</param>
/// <param name="desiredHeight">desired height</param>
/// <returns>Size instance with the resized dimensions</returns>
private static Size CalculateResizedDimensions(Image image, int desiredWidth, int desiredHeight)
{
var widthScale = (double)desiredWidth/image.Width;
var heightScale = (double)desiredHeight/image.Height;
// scale to whichever ratio is smaller, this works for both scaling up and scaling down
var scale = widthScale < heightScale ? widthScale : heightScale;
return new Size
{
Width = (int) (scale * image.Width),
Height = (int) (scale * image.Height)
};
}
Merci d'avoir indiqué la solution au problème de la bordure grise. –
Comme ci-dessus, merci pour le problème de la frontière. –
Cette solution redimensionne sans changer les couleurs de l'image originale! Bon travail! – danyolgiax
Le code associé au redimensionnement réel du bitmap est le suivant.
public static Bitmap ResizeBitmap(Bitmap originalBitmap, int requiredHeight, int requiredWidth)
{
int[] heightWidthRequiredDimensions;
// Pass dimensions to worker method depending on image type required
heightWidthRequiredDimensions = WorkDimensions(originalBitmap.Height, originalBitmap.Width, requiredHeight, requiredWidth);
Bitmap resizedBitmap = new Bitmap(heightWidthRequiredDimensions[1],
heightWidthRequiredDimensions[0]);
const float resolution = 72;
resizedBitmap.SetResolution(resolution, resolution);
Graphics graphic = Graphics.FromImage((Image) resizedBitmap);
graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphic.DrawImage(originalBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height);
graphic.Dispose();
originalBitmap.Dispose();
//resizedBitmap.Dispose(); // Still in use
return resizedBitmap;
}
private static int[] WorkDimensions(int originalHeight, int originalWidth, int requiredHeight, int requiredWidth)
{
int imgHeight = 0;
int imgWidth = 0;
imgWidth = requiredHeight;
imgHeight = requiredWidth;
int requiredHeightLocal = originalHeight;
int requiredWidthLocal = originalWidth;
double ratio = 0;
// Check height first
// If original height exceeds maximum, get new height and work ratio.
if (originalHeight > imgHeight)
{
ratio = double.Parse(((double) imgHeight/(double) originalHeight).ToString());
requiredHeightLocal = imgHeight;
requiredWidthLocal = (int) ((decimal) originalWidth * (decimal) ratio);
}
// Check width second. It will most likely have been sized down enough
// in the previous if statement. If not, change both dimensions here by width.
// If new width exceeds maximum, get new width and height ratio.
if (requiredWidthLocal >= imgWidth)
{
ratio = double.Parse(((double) imgWidth/(double) originalWidth).ToString());
requiredWidthLocal = imgWidth;
requiredHeightLocal = (int) ((double) originalHeight * (double) ratio);
}
int[] heightWidthDimensionArr = { requiredHeightLocal, requiredWidthLocal };
return heightWidthDimensionArr;
}
}
Ce blog contient le code source complet pour le redimensionnement de l'image et la compression (si nécessaire)
http://blog.bombdefused.com/2010/08/bulk-image-optimizer-in-c-full-source.html
Postez le code que vous utilisez cela ne fonctionne pas, et expliquer de quelle manière il ne marche pas. – RedFilter
Vous voulez forcer 103x32? Ou le meilleur ajustement? – citronas
'ImageBuilder.Current.Build (fichier HttpPostedFile, chemin de chaîne, nouveau ResizeSettings (" width = 103 & height = 32 "));' // Utilisation de la bibliothèque [Image Resizer] (http://imageresizing.net) –