Я разрабатываю веб-приложение ASP.NET 3.5, в котором я разрешаю своим пользователям загружать изображения jpeg, gif, bmp или png. Если размер загруженного изображения больше, чем 103 x 32, я хочу изменить размер загруженного изображения на 103 x 32. Я прочитал несколько статей и статей в блоге, а также попробовал некоторые примеры кода, но ничего не работает правильно. Кто-нибудь преуспеет в этом?Изменение размера изображения в asp.net без потери качества изображения
ответ
У меня была та же проблема, некоторое время назад и имел дело с ним так:
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);
}
Я только что прочитал, что это был способ получить самое высокое качество.
+1 Nice : "Double ratio = Math.Max (xRatio, yRatio);" – Joop
В новой версии я также принимаю во внимание, что я не буду растягивать изображения, но это должно быть довольно легко выработать: -P (hint: 'ration = Math.Min (ration, 1.0);') – Alxandr
Well , есть [несколько дополнительных настроек, которые помогут] (http://nathanaeljones.com/163/20-image-resizing-pitfalls/), например смещение пикселей. –
Я успешно сделал это, создав растровое изображение, а затем изменив размер растрового изображения ... Я не уверен, что это лучший или самый эффективный способ сделать это, но он работает для меня.
В моем случае мне нужно было разрезать высоту и ширину изображения наполовину.
Вот что я сделал.
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;
}
Это код, который я использую. Он поддерживает вращение, а также устанавливает разрешение изображения в соответствии со стандартами JPEG с разрешением 72dpi @ 24-bit (по умолчанию GDI + сохраняет изображения с разрешением 96dpi при 32-битном цвете). Он также устраняет проблему с черной/серой границей, которую испытывают некоторые люди при изменении размеров изображений.
/// <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)
};
}
Благодарим за решение проблемы с серой границей. –
Как и выше, спасибо за исправление проблемы с границей. –
Это решение изменяет размер без изменений исходных цветов изображения! Отличная работа! – danyolgiax
Код, связанный с фактическим изменением размера растрового изображения, выглядит следующим образом.
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;
}
}
Этот блог содержит полный исходный код для изменения размера изображения и сжатие (если требуется)
http://blog.bombdefused.com/2010/08/bulk-image-optimizer-in-c-full-source.html
Post код, который вы используете, что не работает, и объяснить, каким образом это не работает. – RedFilter
Вы хотите заставить 103x32? Или лучше всего подходит? – citronas
'ImageBuilder.Current.Build (файл HttpPostedFile, строковый путь, новый ResizeSettings (" width = 103 & height = 32 ")); // Использование библиотеки [Image Resizer library] (http://imageresizing.net) –