Related
I'm trying to resize an image while preserving the aspect ratio from the original image so the new image doesn't look squashed.
eg:
Convert a 150*100 image into a 150*150 image.
The extra 50 pixels of the height need to be padded with a white background color.
This is the current code I am using.
It works well for resizing but changing the aspect ratio of the original image squashes the new image.
private void resizeImage(string path, string originalFilename,
int width, int height)
{
Image image = Image.FromFile(path + originalFilename);
System.Drawing.Image thumbnail = new Bitmap(width, height);
System.Drawing.Graphics graphic =
System.Drawing.Graphics.FromImage(thumbnail);
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;
graphic.DrawImage(image, 0, 0, width, height);
System.Drawing.Imaging.ImageCodecInfo[] info =
ImageCodecInfo.GetImageEncoders();
EncoderParameters encoderParameters;
encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,
100L);
thumbnail.Save(path + width + "." + originalFilename, info[1],
encoderParameters);
}
EDIT: I'd like to have the image padded instead of cropped
This should do it.
private void resizeImage(string path, string originalFilename,
/* note changed names */
int canvasWidth, int canvasHeight,
/* new */
int originalWidth, int originalHeight)
{
Image image = Image.FromFile(path + originalFilename);
System.Drawing.Image thumbnail =
new Bitmap(canvasWidth, canvasHeight); // changed parm names
System.Drawing.Graphics graphic =
System.Drawing.Graphics.FromImage(thumbnail);
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;
/* ------------------ new code --------------- */
// Figure out the ratio
double ratioX = (double) canvasWidth / (double) originalWidth;
double ratioY = (double) canvasHeight / (double) originalHeight;
// use whichever multiplier is smaller
double ratio = ratioX < ratioY ? ratioX : ratioY;
// now we can get the new height and width
int newHeight = Convert.ToInt32(originalHeight * ratio);
int newWidth = Convert.ToInt32(originalWidth * ratio);
// Now calculate the X,Y position of the upper-left corner
// (one of these will always be zero)
int posX = Convert.ToInt32((canvasWidth - (originalWidth * ratio)) / 2);
int posY = Convert.ToInt32((canvasHeight - (originalHeight * ratio)) / 2);
graphic.Clear(Color.White); // white padding
graphic.DrawImage(image, posX, posY, newWidth, newHeight);
/* ------------- end new code ---------------- */
System.Drawing.Imaging.ImageCodecInfo[] info =
ImageCodecInfo.GetImageEncoders();
EncoderParameters encoderParameters;
encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,
100L);
thumbnail.Save(path + newWidth + "." + originalFilename, info[1],
encoderParameters);
}
Edited to add:
Those who want to improve this code should put it in the comments, or a new answer. Don't edit this code directly.
I found out how to resize AND pad the image by learning from this this CodeProject Article.
static Image FixedSize(Image imgPhoto, int Width, int Height)
{
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
int sourceX = 0;
int sourceY = 0;
int destX = 0;
int destY = 0;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)Width / (float)sourceWidth);
nPercentH = ((float)Height / (float)sourceHeight);
if (nPercentH < nPercentW)
{
nPercent = nPercentH;
destX = System.Convert.ToInt16((Width -
(sourceWidth * nPercent)) / 2);
}
else
{
nPercent = nPercentW;
destY = System.Convert.ToInt16((Height -
(sourceHeight * nPercent)) / 2);
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(Width, Height,
PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.Clear(Color.Red);
grPhoto.InterpolationMode =
InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
I use the following method to calculate the desired image size:
using System.Drawing;
public static Size ResizeKeepAspect(this Size src, int maxWidth, int maxHeight, bool enlarge = false)
{
maxWidth = enlarge ? maxWidth : Math.Min(maxWidth, src.Width);
maxHeight = enlarge ? maxHeight : Math.Min(maxHeight, src.Height);
decimal rnd = Math.Min(maxWidth / (decimal)src.Width, maxHeight / (decimal)src.Height);
return new Size((int)Math.Round(src.Width * rnd), (int)Math.Round(src.Height * rnd));
}
This puts the problem of aspect ratio and dimensions in a separate method.
What does the parameter bool enlarge = false ?
usually you do only shrinking of images because enlarging means quality loss - so I added this optional parameter if you want to do it anyway
To get a faster result, the function that obtains the size could be found in resultSize:
Size original = new Size(640, 480);
int maxSize = 100;
float percent = (new List<float> { (float)maxSize / (float)original.Width , (float)maxSize / (float)original.Height }).Min();
Size resultSize = new Size((int)Math.Floor(original.Width * percent), (int)Math.Floor(original.Height * percent));
Uses Linq to minimize variable and recalculations, as well as unnecesary if/else statements
Just generalizing it down to aspect ratios and sizes, image stuff can be done outside of this function
public static d.RectangleF ScaleRect(d.RectangleF dest, d.RectangleF src,
bool keepWidth, bool keepHeight)
{
d.RectangleF destRect = new d.RectangleF();
float sourceAspect = src.Width / src.Height;
float destAspect = dest.Width / dest.Height;
if (sourceAspect > destAspect)
{
// wider than high keep the width and scale the height
destRect.Width = dest.Width;
destRect.Height = dest.Width / sourceAspect;
if (keepHeight)
{
float resizePerc = dest.Height / destRect.Height;
destRect.Width = dest.Width * resizePerc;
destRect.Height = dest.Height;
}
}
else
{
// higher than wide – keep the height and scale the width
destRect.Height = dest.Height;
destRect.Width = dest.Height * sourceAspect;
if (keepWidth)
{
float resizePerc = dest.Width / destRect.Width;
destRect.Width = dest.Width;
destRect.Height = dest.Height * resizePerc;
}
}
return destRect;
}
I'm going to add my code here too. This code will allow you resize an image with or without the aspect ratio being enforced or to resize with padding. This is a modified version of egrunin's code.
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
namespace ConsoleApplication1
{
public class Program
{
public static void Main(string[] args)
{
var path = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
ResizeImage(path, "large.jpg", path, "new.jpg", 100, 100, true, true);
}
/// <summary>Resizes an image to a new width and height.</summary>
/// <param name="originalPath">The folder which holds the original image.</param>
/// <param name="originalFileName">The file name of the original image.</param>
/// <param name="newPath">The folder which will hold the resized image.</param>
/// <param name="newFileName">The file name of the resized image.</param>
/// <param name="maximumWidth">When resizing the image, this is the maximum width to resize the image to.</param>
/// <param name="maximumHeight">When resizing the image, this is the maximum height to resize the image to.</param>
/// <param name="enforceRatio">Indicates whether to keep the width/height ratio aspect or not. If set to false, images with an unequal width and height will be distorted and padding is disregarded. If set to true, the width/height ratio aspect is maintained and distortion does not occur.</param>
/// <param name="addPadding">Indicates whether fill the smaller dimension of the image with a white background. If set to true, the white padding fills the smaller dimension until it reach the specified max width or height. This is used for maintaining a 1:1 ratio if the max width and height are the same.</param>
private static void ResizeImage(string originalPath, string originalFileName, string newPath, string newFileName, int maximumWidth, int maximumHeight, bool enforceRatio, bool addPadding)
{
var image = Image.FromFile(originalPath + "\\" + originalFileName);
var imageEncoders = ImageCodecInfo.GetImageEncoders();
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
var canvasWidth = maximumWidth;
var canvasHeight = maximumHeight;
var newImageWidth = maximumWidth;
var newImageHeight = maximumHeight;
var xPosition = 0;
var yPosition = 0;
if (enforceRatio)
{
var ratioX = maximumWidth / (double)image.Width;
var ratioY = maximumHeight / (double)image.Height;
var ratio = ratioX < ratioY ? ratioX : ratioY;
newImageHeight = (int)(image.Height * ratio);
newImageWidth = (int)(image.Width * ratio);
if (addPadding)
{
xPosition = (int)((maximumWidth - (image.Width * ratio)) / 2);
yPosition = (int)((maximumHeight - (image.Height * ratio)) / 2);
}
else
{
canvasWidth = newImageWidth;
canvasHeight = newImageHeight;
}
}
var thumbnail = new Bitmap(canvasWidth, canvasHeight);
var graphic = Graphics.FromImage(thumbnail);
if (enforceRatio && addPadding)
{
graphic.Clear(Color.White);
}
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;
graphic.DrawImage(image, xPosition, yPosition, newImageWidth, newImageHeight);
thumbnail.Save(newPath + "\\" + newFileName, imageEncoders[1], encoderParameters);
}
}
}
Here's a less specific extension method that works with Image rather than doing the loading and saving for you. It also allows you to specify interpolation method and correctly renders edges when you use NearestNeighbour interpolation.
The image will be rendered within the bounds of the area you specify so you always know your output width and height. e.g:
namespace YourApp
{
#region Namespaces
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
#endregion
/// <summary>Generic helper functions related to graphics.</summary>
public static class ImageExtensions
{
/// <summary>Resizes an image to a new width and height value.</summary>
/// <param name="image">The image to resize.</param>
/// <param name="newWidth">The width of the new image.</param>
/// <param name="newHeight">The height of the new image.</param>
/// <param name="mode">Interpolation mode.</param>
/// <param name="maintainAspectRatio">If true, the image is centered in the middle of the returned image, maintaining the aspect ratio of the original image.</param>
/// <returns>The new image. The old image is unaffected.</returns>
public static Image ResizeImage(this Image image, int newWidth, int newHeight, InterpolationMode mode = InterpolationMode.Default, bool maintainAspectRatio = false)
{
Bitmap output = new Bitmap(newWidth, newHeight, image.PixelFormat);
using (Graphics gfx = Graphics.FromImage(output))
{
gfx.Clear(Color.FromArgb(0, 0, 0, 0));
gfx.InterpolationMode = mode;
if (mode == InterpolationMode.NearestNeighbor)
{
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.SmoothingMode = SmoothingMode.HighQuality;
}
double ratioW = (double)newWidth / (double)image.Width;
double ratioH = (double)newHeight / (double)image.Height;
double ratio = ratioW < ratioH ? ratioW : ratioH;
int insideWidth = (int)(image.Width * ratio);
int insideHeight = (int)(image.Height * ratio);
gfx.DrawImage(image, new Rectangle((newWidth / 2) - (insideWidth / 2), (newHeight / 2) - (insideHeight / 2), insideWidth, insideHeight));
}
return output;
}
}
}
Note: this code resizes and removes everything outside the aspect ratio instead of padding it..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace MyPhotos.Common
{
public class ThumbCreator
{
public enum VerticalAlign
{
Top,
Middle,
Bottom
}
public enum HorizontalAlign
{
Left,
Middle,
Right
}
public void Convert(string sourceFile, string targetFile, ImageFormat targetFormat, int height, int width, VerticalAlign valign, HorizontalAlign halign)
{
using (Image img = Image.FromFile(sourceFile))
{
using (Image targetImg = Convert(img, height, width, valign, halign))
{
string directory = Path.GetDirectoryName(targetFile);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
if (targetFormat == ImageFormat.Jpeg)
{
SaveJpeg(targetFile, targetImg, 100);
}
else
{
targetImg.Save(targetFile, targetFormat);
}
}
}
}
/// <summary>
/// Saves an image as a jpeg image, with the given quality
/// </summary>
/// <param name="path">Path to which the image would be saved.</param>
// <param name="quality">An integer from 0 to 100, with 100 being the
/// highest quality</param>
public static void SaveJpeg(string path, Image img, int quality)
{
if (quality < 0 || quality > 100)
throw new ArgumentOutOfRangeException("quality must be between 0 and 100.");
// Encoder parameter for image quality
EncoderParameter qualityParam =
new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
// Jpeg image codec
ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
img.Save(path, jpegCodec, encoderParams);
}
/// <summary>
/// Returns the image codec with the given mime type
/// </summary>
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
for (int i = 0; i < codecs.Length; i++)
if (codecs[i].MimeType == mimeType)
return codecs[i];
return null;
}
public Image Convert(Image img, int height, int width, VerticalAlign valign, HorizontalAlign halign)
{
Bitmap result = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(result))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
float ratio = (float)height / (float)img.Height;
int temp = (int)((float)img.Width * ratio);
if (temp == width)
{
//no corrections are needed!
g.DrawImage(img, 0, 0, width, height);
return result;
}
else if (temp > width)
{
//den e för bred!
int overFlow = (temp - width);
if (halign == HorizontalAlign.Middle)
{
g.DrawImage(img, 0 - overFlow / 2, 0, temp, height);
}
else if (halign == HorizontalAlign.Left)
{
g.DrawImage(img, 0, 0, temp, height);
}
else if (halign == HorizontalAlign.Right)
{
g.DrawImage(img, -overFlow, 0, temp, height);
}
}
else
{
//den e för hög!
ratio = (float)width / (float)img.Width;
temp = (int)((float)img.Height * ratio);
int overFlow = (temp - height);
if (valign == VerticalAlign.Top)
{
g.DrawImage(img, 0, 0, width, temp);
}
else if (valign == VerticalAlign.Middle)
{
g.DrawImage(img, 0, -overFlow / 2, width, temp);
}
else if (valign == VerticalAlign.Bottom)
{
g.DrawImage(img, 0, -overFlow, width, temp);
}
}
}
return result;
}
}
}
// This allows us to resize the image. It prevents skewed images and
// also vertically long images caused by trying to maintain the aspect
// ratio on images who's height is larger than their width
public void ResizeImage(string OriginalFile, string NewFile, int NewWidth, int MaxHeight, bool OnlyResizeIfWider)
{
System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFile);
// Prevent using images internal thumbnail
FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
if (OnlyResizeIfWider)
{
if (FullsizeImage.Width <= NewWidth)
{
NewWidth = FullsizeImage.Width;
}
}
int NewHeight = FullsizeImage.Height * NewWidth / FullsizeImage.Width;
if (NewHeight > MaxHeight)
{
// Resize with height instead
NewWidth = FullsizeImage.Width * MaxHeight / FullsizeImage.Height;
NewHeight = MaxHeight;
}
System.Drawing.Image NewImage = FullsizeImage.GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero);
// Clear handle to original file so that we can overwrite it if necessary
FullsizeImage.Dispose();
// Save resized picture
NewImage.Save(NewFile);
}
I created a extension method that is much simpiler than the answers that are posted.
and the aspect ratio is applied without cropping the image.
public static Image Resize(this Image image, int width, int height) {
var scale = Math.Min(height / (float)image.Height, width / (float)image.Width);
return image.GetThumbnailImage((int)(image.Width * scale), (int)(image.Height * scale), () => false, IntPtr.Zero);
}
Example usage:
using (var img = Image.FromFile(pathToOriginalImage)) {
using (var thumbnail = img.Resize(60, 60)){
// Here you can do whatever you need to do with thumnail
}
}
Maintain aspect Ration and eliminate letterbox and Pillarbox.
static Image FixedSize(Image imgPhoto, int Width, int Height)
{
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
int X = 0;
int Y = 0;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)Width / (float)sourceWidth);
nPercentH = ((float)Height / (float)sourceHeight);
if (nPercentH < nPercentW)
{
nPercent = nPercentH;
}
else
{
nPercent = nPercentW;
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.DrawImage(imgPhoto,
new Rectangle(X, Y, destWidth, destHeight),
new Rectangle(X, Y, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
public static void resizeImage_n_save(Stream sourcePath, string targetPath, int requiredSize)
{
using (var image = System.Drawing.Image.FromStream(sourcePath))
{
double ratio = 0;
var newWidth = 0;
var newHeight = 0;
double w = Convert.ToInt32(image.Width);
double h = Convert.ToInt32(image.Height);
if (w > h)
{
ratio = h / w * 100;
newWidth = requiredSize;
newHeight = Convert.ToInt32(requiredSize * ratio / 100);
}
else
{
ratio = w / h * 100;
newHeight = requiredSize;
newWidth = Convert.ToInt32(requiredSize * ratio / 100);
}
// var newWidth = (int)(image.Width * scaleFactor);
// var newHeight = (int)(image.Height * scaleFactor);
var thumbnailImg = new Bitmap(newWidth, newHeight);
var thumbGraph = Graphics.FromImage(thumbnailImg);
thumbGraph.CompositingQuality = CompositingQuality.HighQuality;
thumbGraph.SmoothingMode = SmoothingMode.HighQuality;
thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
var imageRectangle = new Rectangle(0, 0, newWidth, newHeight);
thumbGraph.DrawImage(image, imageRectangle);
thumbnailImg.Save(targetPath, image.RawFormat);
//var img = FixedSize(image, requiredSize, requiredSize);
//img.Save(targetPath, image.RawFormat);
}
}
I just wrote this cos none of the answers already here were simple enough. You can replace the hardcoded 128 for whatever you want or base them off the size of the original image. All i wanted was to rescale the image into a 128x128 image, keeping the aspect ratio and centering the result in the new image.
private Bitmap CreateLargeIconForImage(Bitmap src)
{
Bitmap bmp = new Bitmap(128, 128);
Graphics g = Graphics.FromImage(bmp);
float scale = Math.Max((float)src.Width / 128.0f, (float)src.Height / 128.0f);
PointF p = new PointF(128.0f - ((float)src.Width / scale), 128.0f - ((float)src.Height / scale));
SizeF size = new SizeF((float)src.Width / scale, (float)src.Height / scale);
g.DrawImage(src, new RectangleF(p, size));
return bmp;
}
I know this is an older thread. However, this is the first result in a Google search on the topic.
None of the answers fit my requirement. So, here's a solution I put together by understanding the older solutions, but limiting the result image size to the most suitable height and width.
double ratioW = (double)desiredWidthPixels / (double)originalImage.Width;
double ratioH = (double)desiredHeightPixels / (double)originalImage.Height;
double ratio = ratioW < ratioH ? ratioW : ratioH;
int suitableWidth = (int)(originalImage.Width * ratio);
int suitableHeight = (int)(originalImage.Height * ratio);
var resizedPhoto = new Bitmap((int)suitableWidth, (int)suitableHeight);
var graphicsSurface = Graphics.FromImage(resizedPhoto);
graphicsSurface.DrawImage(originalImage, new RectangleF(new PointF(0,0), new SizeF(suitableWidth, suitableHeight)));
I want to insert two different sizes of images using single file upload.
I had inserted one image which has size 101 but I need to insert another 51 size small image of the same user, for that I need my own method.
id BigImage SmallImage
1 mazhar.jpg NULL
2 12_n.jpg NULL
I need result like below:
id BigImage SmallImage
1 mazhar.jpg smallmazhar.jpg
2 12_n.jpg small12_n.jpg
C# code is given below:
protected void Button1_Click(object sender, EventArgs e)
{
//http://forums.asp.net/t/1079883.aspx?PageIndex=1
string Status = string.Empty;
int id = 0;
const int bmpW = 101;
//New image target width
const int bmpH = 101;
//New Image target height
bo.Para1 = FileUpload1.FileName.ToString();// Passing parameter
if ((FileUpload1.HasFile))
{
//Clear the error label text
lblError.Text = "";
//Check to make sure the file to upload has a picture file format extention and set the target width and height
if ((CheckFileType(FileUpload1.FileName)))
{
Int32 newWidth = bmpW;
Int32 newHeight = bmpH;
//Use the uploaded filename for saving without the '.' extension
String upName = FileUpload1.FileName.Substring(0, FileUpload1.FileName.IndexOf("."));
//Set the save path of the resized image, you will need this directory already created in your web site
// string filePath = "~/Upload/" + upName + ".jpg";
bl.Insert_PhotoInfo(bo, out Status, out id);
string filePath = Convert.ToString(id) + bo.Para1;
FileUpload1.PostedFile.SaveAs(Request.ServerVariables["APPL_PHYSICAL_PATH"] + "Upload/" + filePath);
//Create a new Bitmap using the uploaded picture as a Stream
//Set the new bitmap resolution to 72 pixels per inch
Bitmap upBmp = (Bitmap)Bitmap.FromStream(FileUpload1.PostedFile.InputStream);
Bitmap newBmp = new Bitmap(newWidth, newHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
newBmp.SetResolution(72, 72);
//Get the uploaded image width and height
Double upWidth = upBmp.Width;
Double upHeight = upBmp.Height;
int newX = 0;
//Set the new top left drawing position on the image canvas
int newY = 0;
Double reDuce;
//Keep the aspect ratio of image the same if not 4:3 and work out the newX and newY positions
//to ensure the image is always in the centre of the canvas vertically and horizontally
if (upWidth > upHeight)
{
//Landscape picture
reDuce = newWidth / upWidth;
//calculate the width percentage reduction as decimal
newHeight = ((Int32)(upHeight * reDuce));
//reduce the uploaded image height by the reduce amount
newY = ((Int32)((bmpH - newHeight) / 2));
//Position the image centrally down the canvas
newX = 0;
//Picture will be full width
}
else if (upWidth < upHeight)
{
//Portrait picture
reDuce = newHeight / upHeight;
//calculate the height percentage reduction as decimal
newWidth = ((Int32)(upWidth * reDuce));
//reduce the uploaded image height by the reduce amount
newX = ((Int32)((bmpW - newWidth) / 2));
//Position the image centrally across the canvas
newY = 0;
//Picture will be full hieght
}
else if (upWidth == upHeight)
{
//square picture
reDuce = newHeight / upHeight;
//calculate the height percentage reduction as decimal
newWidth = ((Int32)(upWidth * reDuce));
//reduce the uploaded image height by the reduce amount
newX = ((Int32)((bmpW - newWidth) / 2));
//Position the image centrally across the canvas
newY = ((Int32)((bmpH - newHeight) / 2));
//Position the image centrally down the canvas
}
//Create a new image from the uploaded picture using the Graphics class
//Clear the graphic and set the background colour to white
//Use Antialias and High Quality Bicubic to maintain a good quality picture
//Save the new bitmap image using 'Png' picture format and the calculated canvas positioning
Graphics newGraphic = Graphics.FromImage(newBmp);
try
{
newGraphic.Clear(Color.White);
newGraphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
newGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
newGraphic.DrawImage(upBmp, newX, newY, newWidth, newHeight);
newBmp.Save(MapPath(filePath), System.Drawing.Imaging.ImageFormat.Jpeg);
//Show the uploaded resized picture in the image control
Image1.ImageUrl = filePath;
Image1.Visible = true;
}
catch (Exception ex)
{
string newError = ex.Message;
lblError.Text = newError;
}
finally
{
upBmp.Dispose();
newBmp.Dispose();
newGraphic.Dispose();
}
}
else
{
lblError.Text = "Please select a picture with a file format extension of either Bmp, Jpg, Jpeg, Gif or Png.";
}
}
}
Here is your updated code:
protected void Button1_Click(object sender, EventArgs e){
UploadImage(101, "Big");
UploadImage(51, "Small");
}
protected void UploadImage(int size, string name){
//http://forums.asp.net/t/1079883.aspx?PageIndex=1
string Status = string.Empty;
int id = 0;
const int bmpW = size;
//New image target width
const int bmpH = size;
//New Image target height
bo.Para1 = FileUpload1.FileName.ToString() + name;// Passing parameter
if ((FileUpload1.HasFile))
{
//Clear the error label text
lblError.Text = "";
//Check to make sure the file to upload has a picture file format extention and set the target width and height
if ((CheckFileType(FileUpload1.FileName)))
{
Int32 newWidth = bmpW;
Int32 newHeight = bmpH;
//Use the uploaded filename for saving without the '.' extension
String upName = FileUpload1.FileName.Substring(0, FileUpload1.FileName.IndexOf("."));
//Set the save path of the resized image, you will need this directory already created in your web site
// string filePath = "~/Upload/" + upName + ".jpg";
bl.Insert_PhotoInfo(bo, out Status, out id);
string filePath = Convert.ToString(id) + bo.Para1;
FileUpload1.PostedFile.SaveAs(Request.ServerVariables["APPL_PHYSICAL_PATH"] + "Upload/" + filePath);
//Create a new Bitmap using the uploaded picture as a Stream
//Set the new bitmap resolution to 72 pixels per inch
Bitmap upBmp = (Bitmap)Bitmap.FromStream(FileUpload1.PostedFile.InputStream);
Bitmap newBmp = new Bitmap(newWidth, newHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
newBmp.SetResolution(72, 72);
//Get the uploaded image width and height
Double upWidth = upBmp.Width;
Double upHeight = upBmp.Height;
int newX = 0;
//Set the new top left drawing position on the image canvas
int newY = 0;
Double reDuce;
//Keep the aspect ratio of image the same if not 4:3 and work out the newX and newY positions
//to ensure the image is always in the centre of the canvas vertically and horizontally
if (upWidth > upHeight)
{
//Landscape picture
reDuce = newWidth / upWidth;
//calculate the width percentage reduction as decimal
newHeight = ((Int32)(upHeight * reDuce));
//reduce the uploaded image height by the reduce amount
newY = ((Int32)((bmpH - newHeight) / 2));
//Position the image centrally down the canvas
newX = 0;
//Picture will be full width
}
else if (upWidth < upHeight)
{
//Portrait picture
reDuce = newHeight / upHeight;
//calculate the height percentage reduction as decimal
newWidth = ((Int32)(upWidth * reDuce));
//reduce the uploaded image height by the reduce amount
newX = ((Int32)((bmpW - newWidth) / 2));
//Position the image centrally across the canvas
newY = 0;
//Picture will be full hieght
}
else if (upWidth == upHeight)
{
//square picture
reDuce = newHeight / upHeight;
//calculate the height percentage reduction as decimal
newWidth = ((Int32)(upWidth * reDuce));
//reduce the uploaded image height by the reduce amount
newX = ((Int32)((bmpW - newWidth) / 2));
//Position the image centrally across the canvas
newY = ((Int32)((bmpH - newHeight) / 2));
//Position the image centrally down the canvas
}
//Create a new image from the uploaded picture using the Graphics class
//Clear the graphic and set the background colour to white
//Use Antialias and High Quality Bicubic to maintain a good quality picture
//Save the new bitmap image using 'Png' picture format and the calculated canvas positioning
Graphics newGraphic = Graphics.FromImage(newBmp);
try
{
newGraphic.Clear(Color.White);
newGraphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
newGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
newGraphic.DrawImage(upBmp, newX, newY, newWidth, newHeight);
newBmp.Save(MapPath(filePath), System.Drawing.Imaging.ImageFormat.Jpeg);
//Show the uploaded resized picture in the image control
Image1.ImageUrl = filePath;
Image1.Visible = true;
}
catch (Exception ex)
{
string newError = ex.Message;
lblError.Text = newError;
}
finally
{
upBmp.Dispose();
newBmp.Dispose();
newGraphic.Dispose();
}
}
else
{
lblError.Text = "Please select a picture with a file format extension of either Bmp, Jpg, Jpeg, Gif or Png.";
}
}
}
I have a method that takes in a bitmap object and overlays dates and times strings over it and returns that new bitmap. The code is below.
public static Bitmap overlayBitmap(Bitmap sourceBMP, int width, int height, List<String> times, List<String> dates, IEnumerable<Color> colors) {
// Determine the new width
float newWidth = width + (width / 3.0f);
float newHeight = height + (height / 3.0f);
// Intelligent vertical + horizontal text distance calculator
float verticalDistance = height / (times.Count - 1.0f);
float horizontalDistance = width / (dates.Count - 1.0f);
Bitmap result = new Bitmap((int)newWidth, (int)newHeight);
using (Graphics g = Graphics.FromImage(result)) {
// Background color
Brush brush = new SolidBrush(colors.First());
g.FillRectangle(brush, 0, 0, newWidth, newHeight);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
// Times text configs
StringFormat stringFormatTimes = new StringFormat();
stringFormatTimes.LineAlignment = StringAlignment.Center;
stringFormatTimes.Alignment = StringAlignment.Center;
Font drawFontY = new Font("Whitney", newHeight / 70);
// Dates text configs
StringFormat stringFormatDates = new StringFormat();
stringFormatDates.LineAlignment = StringAlignment.Center;
stringFormatTimes.Alignment = StringAlignment.Center;
stringFormatDates.FormatFlags = StringFormatFlags.DirectionVertical;
Font drawFontX = new Font("Whitney", newHeight / 70);
// Location of times text
for (int i = 0; i < times.Count; i++) {
if (i % determineIncrementTimes(times.Count) == 0) {
g.DrawString(times[i], drawFontX, Brushes.White, (((newWidth - width) / 2) / 2), ((newHeight - height) / 2) + (verticalDistance * i), stringFormatTimes);
}
}
// Location of dates text
for (int i = 0; i < dates.Count; i++) {
if (i % determineIncrementDates(dates.Count) == 0) {
g.DrawString(dates[i], drawFontY, Brushes.White, ((newWidth - width) / 2) + (horizontalDistance * i), ((newHeight - height) / 2) + height, stringFormatDates);
}
}
// New X and Y Position of the sourceBMP within the new BMP.
int XPos = width / 6;
int YPos = height / 6;
// Int -> Float casting for the outline
float fXPos = width / 6.0f;
float fYPos = height / 6.0f;
float fWidth = width / 1.0f;
float fHeight = height / 1.0f;
// Draw new image at the position width/6 and height/6 with the size at width and height
g.DrawImage(sourceBMP, fXPos, fYPos, fWidth, fHeight);
g.DrawRectangle(Pens.White, fXPos, fYPos, fWidth, fHeight); // white outline
g.Dispose();
}
return result;
}
My concern is, I would like to be able, for the next developer, to easily access and set particular values that currently I've only "hardcoded" in. An example being the x-position of the time text calculated via this snippet of code:
(((newWidth - width) / 2) / 2)
Realistically I'd like to have the developer be able to access and/or set this value through simply typing in:
something.XPos = [someFloat];
How my method above is used (is pseudo-code) is as the following:
private readonly Bitmap _image;
private readonly Bitmap _overlayedImage;
public myConstructor(int someInputValues){
// some code that generates the first bitmap called _image
_newImage = overlayImage(_image, ....);
}
For reference this is the image drawn:
My question is - since some values need to be casted and initialized first, can I set my instance variables at the end of the method, before the closing brace?
public Bitmap overlayBitmap
{
get
{
// Build bitmap overlay
return overlayBitmapOutput;
}
...
}
[Edit: Answer Insufficient >> Wait]
I'm trying to resize an image while preserving the aspect ratio from the original image so the new image doesn't look squashed.
eg:
Convert a 150*100 image into a 150*150 image.
The extra 50 pixels of the height need to be padded with a white background color.
This is the current code I am using.
It works well for resizing but changing the aspect ratio of the original image squashes the new image.
private void resizeImage(string path, string originalFilename,
int width, int height)
{
Image image = Image.FromFile(path + originalFilename);
System.Drawing.Image thumbnail = new Bitmap(width, height);
System.Drawing.Graphics graphic =
System.Drawing.Graphics.FromImage(thumbnail);
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;
graphic.DrawImage(image, 0, 0, width, height);
System.Drawing.Imaging.ImageCodecInfo[] info =
ImageCodecInfo.GetImageEncoders();
EncoderParameters encoderParameters;
encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,
100L);
thumbnail.Save(path + width + "." + originalFilename, info[1],
encoderParameters);
}
EDIT: I'd like to have the image padded instead of cropped
This should do it.
private void resizeImage(string path, string originalFilename,
/* note changed names */
int canvasWidth, int canvasHeight,
/* new */
int originalWidth, int originalHeight)
{
Image image = Image.FromFile(path + originalFilename);
System.Drawing.Image thumbnail =
new Bitmap(canvasWidth, canvasHeight); // changed parm names
System.Drawing.Graphics graphic =
System.Drawing.Graphics.FromImage(thumbnail);
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;
/* ------------------ new code --------------- */
// Figure out the ratio
double ratioX = (double) canvasWidth / (double) originalWidth;
double ratioY = (double) canvasHeight / (double) originalHeight;
// use whichever multiplier is smaller
double ratio = ratioX < ratioY ? ratioX : ratioY;
// now we can get the new height and width
int newHeight = Convert.ToInt32(originalHeight * ratio);
int newWidth = Convert.ToInt32(originalWidth * ratio);
// Now calculate the X,Y position of the upper-left corner
// (one of these will always be zero)
int posX = Convert.ToInt32((canvasWidth - (originalWidth * ratio)) / 2);
int posY = Convert.ToInt32((canvasHeight - (originalHeight * ratio)) / 2);
graphic.Clear(Color.White); // white padding
graphic.DrawImage(image, posX, posY, newWidth, newHeight);
/* ------------- end new code ---------------- */
System.Drawing.Imaging.ImageCodecInfo[] info =
ImageCodecInfo.GetImageEncoders();
EncoderParameters encoderParameters;
encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,
100L);
thumbnail.Save(path + newWidth + "." + originalFilename, info[1],
encoderParameters);
}
Edited to add:
Those who want to improve this code should put it in the comments, or a new answer. Don't edit this code directly.
I found out how to resize AND pad the image by learning from this this CodeProject Article.
static Image FixedSize(Image imgPhoto, int Width, int Height)
{
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
int sourceX = 0;
int sourceY = 0;
int destX = 0;
int destY = 0;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)Width / (float)sourceWidth);
nPercentH = ((float)Height / (float)sourceHeight);
if (nPercentH < nPercentW)
{
nPercent = nPercentH;
destX = System.Convert.ToInt16((Width -
(sourceWidth * nPercent)) / 2);
}
else
{
nPercent = nPercentW;
destY = System.Convert.ToInt16((Height -
(sourceHeight * nPercent)) / 2);
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(Width, Height,
PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.Clear(Color.Red);
grPhoto.InterpolationMode =
InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
I use the following method to calculate the desired image size:
using System.Drawing;
public static Size ResizeKeepAspect(this Size src, int maxWidth, int maxHeight, bool enlarge = false)
{
maxWidth = enlarge ? maxWidth : Math.Min(maxWidth, src.Width);
maxHeight = enlarge ? maxHeight : Math.Min(maxHeight, src.Height);
decimal rnd = Math.Min(maxWidth / (decimal)src.Width, maxHeight / (decimal)src.Height);
return new Size((int)Math.Round(src.Width * rnd), (int)Math.Round(src.Height * rnd));
}
This puts the problem of aspect ratio and dimensions in a separate method.
What does the parameter bool enlarge = false ?
usually you do only shrinking of images because enlarging means quality loss - so I added this optional parameter if you want to do it anyway
To get a faster result, the function that obtains the size could be found in resultSize:
Size original = new Size(640, 480);
int maxSize = 100;
float percent = (new List<float> { (float)maxSize / (float)original.Width , (float)maxSize / (float)original.Height }).Min();
Size resultSize = new Size((int)Math.Floor(original.Width * percent), (int)Math.Floor(original.Height * percent));
Uses Linq to minimize variable and recalculations, as well as unnecesary if/else statements
Just generalizing it down to aspect ratios and sizes, image stuff can be done outside of this function
public static d.RectangleF ScaleRect(d.RectangleF dest, d.RectangleF src,
bool keepWidth, bool keepHeight)
{
d.RectangleF destRect = new d.RectangleF();
float sourceAspect = src.Width / src.Height;
float destAspect = dest.Width / dest.Height;
if (sourceAspect > destAspect)
{
// wider than high keep the width and scale the height
destRect.Width = dest.Width;
destRect.Height = dest.Width / sourceAspect;
if (keepHeight)
{
float resizePerc = dest.Height / destRect.Height;
destRect.Width = dest.Width * resizePerc;
destRect.Height = dest.Height;
}
}
else
{
// higher than wide – keep the height and scale the width
destRect.Height = dest.Height;
destRect.Width = dest.Height * sourceAspect;
if (keepWidth)
{
float resizePerc = dest.Width / destRect.Width;
destRect.Width = dest.Width;
destRect.Height = dest.Height * resizePerc;
}
}
return destRect;
}
I'm going to add my code here too. This code will allow you resize an image with or without the aspect ratio being enforced or to resize with padding. This is a modified version of egrunin's code.
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
namespace ConsoleApplication1
{
public class Program
{
public static void Main(string[] args)
{
var path = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
ResizeImage(path, "large.jpg", path, "new.jpg", 100, 100, true, true);
}
/// <summary>Resizes an image to a new width and height.</summary>
/// <param name="originalPath">The folder which holds the original image.</param>
/// <param name="originalFileName">The file name of the original image.</param>
/// <param name="newPath">The folder which will hold the resized image.</param>
/// <param name="newFileName">The file name of the resized image.</param>
/// <param name="maximumWidth">When resizing the image, this is the maximum width to resize the image to.</param>
/// <param name="maximumHeight">When resizing the image, this is the maximum height to resize the image to.</param>
/// <param name="enforceRatio">Indicates whether to keep the width/height ratio aspect or not. If set to false, images with an unequal width and height will be distorted and padding is disregarded. If set to true, the width/height ratio aspect is maintained and distortion does not occur.</param>
/// <param name="addPadding">Indicates whether fill the smaller dimension of the image with a white background. If set to true, the white padding fills the smaller dimension until it reach the specified max width or height. This is used for maintaining a 1:1 ratio if the max width and height are the same.</param>
private static void ResizeImage(string originalPath, string originalFileName, string newPath, string newFileName, int maximumWidth, int maximumHeight, bool enforceRatio, bool addPadding)
{
var image = Image.FromFile(originalPath + "\\" + originalFileName);
var imageEncoders = ImageCodecInfo.GetImageEncoders();
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
var canvasWidth = maximumWidth;
var canvasHeight = maximumHeight;
var newImageWidth = maximumWidth;
var newImageHeight = maximumHeight;
var xPosition = 0;
var yPosition = 0;
if (enforceRatio)
{
var ratioX = maximumWidth / (double)image.Width;
var ratioY = maximumHeight / (double)image.Height;
var ratio = ratioX < ratioY ? ratioX : ratioY;
newImageHeight = (int)(image.Height * ratio);
newImageWidth = (int)(image.Width * ratio);
if (addPadding)
{
xPosition = (int)((maximumWidth - (image.Width * ratio)) / 2);
yPosition = (int)((maximumHeight - (image.Height * ratio)) / 2);
}
else
{
canvasWidth = newImageWidth;
canvasHeight = newImageHeight;
}
}
var thumbnail = new Bitmap(canvasWidth, canvasHeight);
var graphic = Graphics.FromImage(thumbnail);
if (enforceRatio && addPadding)
{
graphic.Clear(Color.White);
}
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;
graphic.DrawImage(image, xPosition, yPosition, newImageWidth, newImageHeight);
thumbnail.Save(newPath + "\\" + newFileName, imageEncoders[1], encoderParameters);
}
}
}
Here's a less specific extension method that works with Image rather than doing the loading and saving for you. It also allows you to specify interpolation method and correctly renders edges when you use NearestNeighbour interpolation.
The image will be rendered within the bounds of the area you specify so you always know your output width and height. e.g:
namespace YourApp
{
#region Namespaces
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
#endregion
/// <summary>Generic helper functions related to graphics.</summary>
public static class ImageExtensions
{
/// <summary>Resizes an image to a new width and height value.</summary>
/// <param name="image">The image to resize.</param>
/// <param name="newWidth">The width of the new image.</param>
/// <param name="newHeight">The height of the new image.</param>
/// <param name="mode">Interpolation mode.</param>
/// <param name="maintainAspectRatio">If true, the image is centered in the middle of the returned image, maintaining the aspect ratio of the original image.</param>
/// <returns>The new image. The old image is unaffected.</returns>
public static Image ResizeImage(this Image image, int newWidth, int newHeight, InterpolationMode mode = InterpolationMode.Default, bool maintainAspectRatio = false)
{
Bitmap output = new Bitmap(newWidth, newHeight, image.PixelFormat);
using (Graphics gfx = Graphics.FromImage(output))
{
gfx.Clear(Color.FromArgb(0, 0, 0, 0));
gfx.InterpolationMode = mode;
if (mode == InterpolationMode.NearestNeighbor)
{
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.SmoothingMode = SmoothingMode.HighQuality;
}
double ratioW = (double)newWidth / (double)image.Width;
double ratioH = (double)newHeight / (double)image.Height;
double ratio = ratioW < ratioH ? ratioW : ratioH;
int insideWidth = (int)(image.Width * ratio);
int insideHeight = (int)(image.Height * ratio);
gfx.DrawImage(image, new Rectangle((newWidth / 2) - (insideWidth / 2), (newHeight / 2) - (insideHeight / 2), insideWidth, insideHeight));
}
return output;
}
}
}
Note: this code resizes and removes everything outside the aspect ratio instead of padding it..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace MyPhotos.Common
{
public class ThumbCreator
{
public enum VerticalAlign
{
Top,
Middle,
Bottom
}
public enum HorizontalAlign
{
Left,
Middle,
Right
}
public void Convert(string sourceFile, string targetFile, ImageFormat targetFormat, int height, int width, VerticalAlign valign, HorizontalAlign halign)
{
using (Image img = Image.FromFile(sourceFile))
{
using (Image targetImg = Convert(img, height, width, valign, halign))
{
string directory = Path.GetDirectoryName(targetFile);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
if (targetFormat == ImageFormat.Jpeg)
{
SaveJpeg(targetFile, targetImg, 100);
}
else
{
targetImg.Save(targetFile, targetFormat);
}
}
}
}
/// <summary>
/// Saves an image as a jpeg image, with the given quality
/// </summary>
/// <param name="path">Path to which the image would be saved.</param>
// <param name="quality">An integer from 0 to 100, with 100 being the
/// highest quality</param>
public static void SaveJpeg(string path, Image img, int quality)
{
if (quality < 0 || quality > 100)
throw new ArgumentOutOfRangeException("quality must be between 0 and 100.");
// Encoder parameter for image quality
EncoderParameter qualityParam =
new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
// Jpeg image codec
ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
img.Save(path, jpegCodec, encoderParams);
}
/// <summary>
/// Returns the image codec with the given mime type
/// </summary>
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
for (int i = 0; i < codecs.Length; i++)
if (codecs[i].MimeType == mimeType)
return codecs[i];
return null;
}
public Image Convert(Image img, int height, int width, VerticalAlign valign, HorizontalAlign halign)
{
Bitmap result = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(result))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
float ratio = (float)height / (float)img.Height;
int temp = (int)((float)img.Width * ratio);
if (temp == width)
{
//no corrections are needed!
g.DrawImage(img, 0, 0, width, height);
return result;
}
else if (temp > width)
{
//den e för bred!
int overFlow = (temp - width);
if (halign == HorizontalAlign.Middle)
{
g.DrawImage(img, 0 - overFlow / 2, 0, temp, height);
}
else if (halign == HorizontalAlign.Left)
{
g.DrawImage(img, 0, 0, temp, height);
}
else if (halign == HorizontalAlign.Right)
{
g.DrawImage(img, -overFlow, 0, temp, height);
}
}
else
{
//den e för hög!
ratio = (float)width / (float)img.Width;
temp = (int)((float)img.Height * ratio);
int overFlow = (temp - height);
if (valign == VerticalAlign.Top)
{
g.DrawImage(img, 0, 0, width, temp);
}
else if (valign == VerticalAlign.Middle)
{
g.DrawImage(img, 0, -overFlow / 2, width, temp);
}
else if (valign == VerticalAlign.Bottom)
{
g.DrawImage(img, 0, -overFlow, width, temp);
}
}
}
return result;
}
}
}
// This allows us to resize the image. It prevents skewed images and
// also vertically long images caused by trying to maintain the aspect
// ratio on images who's height is larger than their width
public void ResizeImage(string OriginalFile, string NewFile, int NewWidth, int MaxHeight, bool OnlyResizeIfWider)
{
System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFile);
// Prevent using images internal thumbnail
FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
if (OnlyResizeIfWider)
{
if (FullsizeImage.Width <= NewWidth)
{
NewWidth = FullsizeImage.Width;
}
}
int NewHeight = FullsizeImage.Height * NewWidth / FullsizeImage.Width;
if (NewHeight > MaxHeight)
{
// Resize with height instead
NewWidth = FullsizeImage.Width * MaxHeight / FullsizeImage.Height;
NewHeight = MaxHeight;
}
System.Drawing.Image NewImage = FullsizeImage.GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero);
// Clear handle to original file so that we can overwrite it if necessary
FullsizeImage.Dispose();
// Save resized picture
NewImage.Save(NewFile);
}
I created a extension method that is much simpiler than the answers that are posted.
and the aspect ratio is applied without cropping the image.
public static Image Resize(this Image image, int width, int height) {
var scale = Math.Min(height / (float)image.Height, width / (float)image.Width);
return image.GetThumbnailImage((int)(image.Width * scale), (int)(image.Height * scale), () => false, IntPtr.Zero);
}
Example usage:
using (var img = Image.FromFile(pathToOriginalImage)) {
using (var thumbnail = img.Resize(60, 60)){
// Here you can do whatever you need to do with thumnail
}
}
Maintain aspect Ration and eliminate letterbox and Pillarbox.
static Image FixedSize(Image imgPhoto, int Width, int Height)
{
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
int X = 0;
int Y = 0;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)Width / (float)sourceWidth);
nPercentH = ((float)Height / (float)sourceHeight);
if (nPercentH < nPercentW)
{
nPercent = nPercentH;
}
else
{
nPercent = nPercentW;
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.DrawImage(imgPhoto,
new Rectangle(X, Y, destWidth, destHeight),
new Rectangle(X, Y, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
public static void resizeImage_n_save(Stream sourcePath, string targetPath, int requiredSize)
{
using (var image = System.Drawing.Image.FromStream(sourcePath))
{
double ratio = 0;
var newWidth = 0;
var newHeight = 0;
double w = Convert.ToInt32(image.Width);
double h = Convert.ToInt32(image.Height);
if (w > h)
{
ratio = h / w * 100;
newWidth = requiredSize;
newHeight = Convert.ToInt32(requiredSize * ratio / 100);
}
else
{
ratio = w / h * 100;
newHeight = requiredSize;
newWidth = Convert.ToInt32(requiredSize * ratio / 100);
}
// var newWidth = (int)(image.Width * scaleFactor);
// var newHeight = (int)(image.Height * scaleFactor);
var thumbnailImg = new Bitmap(newWidth, newHeight);
var thumbGraph = Graphics.FromImage(thumbnailImg);
thumbGraph.CompositingQuality = CompositingQuality.HighQuality;
thumbGraph.SmoothingMode = SmoothingMode.HighQuality;
thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
var imageRectangle = new Rectangle(0, 0, newWidth, newHeight);
thumbGraph.DrawImage(image, imageRectangle);
thumbnailImg.Save(targetPath, image.RawFormat);
//var img = FixedSize(image, requiredSize, requiredSize);
//img.Save(targetPath, image.RawFormat);
}
}
I just wrote this cos none of the answers already here were simple enough. You can replace the hardcoded 128 for whatever you want or base them off the size of the original image. All i wanted was to rescale the image into a 128x128 image, keeping the aspect ratio and centering the result in the new image.
private Bitmap CreateLargeIconForImage(Bitmap src)
{
Bitmap bmp = new Bitmap(128, 128);
Graphics g = Graphics.FromImage(bmp);
float scale = Math.Max((float)src.Width / 128.0f, (float)src.Height / 128.0f);
PointF p = new PointF(128.0f - ((float)src.Width / scale), 128.0f - ((float)src.Height / scale));
SizeF size = new SizeF((float)src.Width / scale, (float)src.Height / scale);
g.DrawImage(src, new RectangleF(p, size));
return bmp;
}
I know this is an older thread. However, this is the first result in a Google search on the topic.
None of the answers fit my requirement. So, here's a solution I put together by understanding the older solutions, but limiting the result image size to the most suitable height and width.
double ratioW = (double)desiredWidthPixels / (double)originalImage.Width;
double ratioH = (double)desiredHeightPixels / (double)originalImage.Height;
double ratio = ratioW < ratioH ? ratioW : ratioH;
int suitableWidth = (int)(originalImage.Width * ratio);
int suitableHeight = (int)(originalImage.Height * ratio);
var resizedPhoto = new Bitmap((int)suitableWidth, (int)suitableHeight);
var graphicsSurface = Graphics.FromImage(resizedPhoto);
graphicsSurface.DrawImage(originalImage, new RectangleF(new PointF(0,0), new SizeF(suitableWidth, suitableHeight)));
As Size, Width and Height are Get() properties of System.Drawing.Image;
How can I resize an Image object at run-time in C#?
Right now, I am just creating a new Image using:
// objImage is the original Image
Bitmap objBitmap = new Bitmap(objImage, new Size(227, 171));
This will perform a high quality resize:
/// <summary>
/// Resize the image to the specified width and height.
/// </summary>
/// <param name="image">The image to resize.</param>
/// <param name="width">The width to resize to.</param>
/// <param name="height">The height to resize to.</param>
/// <returns>The resized image.</returns>
public static Bitmap ResizeImage(Image image, int width, int height)
{
var destRect = new Rectangle(0, 0, width, height);
var destImage = new Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width,image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
wrapMode.SetWrapMode(WrapMode.TileFlipXY) prevents ghosting around the image borders -- naïve resizing will sample transparent pixels beyond the image boundaries, but by mirroring the image we can get a better sample (this setting is very noticeable)
destImage.SetResolution maintains DPI regardless of physical size -- may increase quality when reducing image dimensions or when printing
Compositing controls how pixels are blended with the background -- might not be needed since we're only drawing one thing.
graphics.CompositingMode determines whether pixels from a source image overwrite or are combined with background pixels. SourceCopy specifies that when a color is rendered, it overwrites the background color.
graphics.CompositingQuality determines the rendering quality level of layered images.
graphics.InterpolationMode determines how intermediate values between two endpoints are calculated
graphics.SmoothingMode specifies whether lines, curves, and the edges of filled areas use smoothing (also called antialiasing) -- probably only works on vectors
graphics.PixelOffsetMode affects rendering quality when drawing the new image
Maintaining aspect ratio is left as an exercise for the reader (actually, I just don't think it's this function's job to do that for you).
Also, this is a good article describing some of the pitfalls with image resizing. The above function will cover most of them, but you still have to worry about saving.
Not sure what is so difficult about this, do what you were doing, use the overloaded Bitmap constructor to create a re-sized image, the only thing you were missing was a cast back to the Image data type:
public static Image resizeImage(Image imgToResize, Size size)
{
return (Image)(new Bitmap(imgToResize, size));
}
yourImage = resizeImage(yourImage, new Size(50,50));
in this question, you'll have some answers, including mine:
public Image resizeImage(int newWidth, int newHeight, string stPhotoPath)
{
Image imgPhoto = Image.FromFile(stPhotoPath);
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
//Consider vertical pics
if (sourceWidth < sourceHeight)
{
int buff = newWidth;
newWidth = newHeight;
newHeight = buff;
}
int sourceX = 0, sourceY = 0, destX = 0, destY = 0;
float nPercent = 0, nPercentW = 0, nPercentH = 0;
nPercentW = ((float)newWidth / (float)sourceWidth);
nPercentH = ((float)newHeight / (float)sourceHeight);
if (nPercentH < nPercentW)
{
nPercent = nPercentH;
destX = System.Convert.ToInt16((newWidth -
(sourceWidth * nPercent)) / 2);
}
else
{
nPercent = nPercentW;
destY = System.Convert.ToInt16((newHeight -
(sourceHeight * nPercent)) / 2);
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(newWidth, newHeight,
PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.Clear(Color.Black);
grPhoto.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
imgPhoto.Dispose();
return bmPhoto;
}
You could try net-vips, the C# binding for libvips. It's a lazy, streaming, demand-driven image processing library, so it can do operations like this without needing to load the whole image.
For example, it comes with a handy image thumbnailer:
using Image image = Image.Thumbnail("image.jpg", 300, 300);
image.WriteToFile("my-thumbnail.jpg");
It also supports smart crop, a way of intelligently determining the most important part of the image and keeping it in focus while cropping the image. For example:
using Image image = Image.Thumbnail("owl.jpg", 128, crop: Enums.Interesting.Attention);
image.WriteToFile("tn_owl.jpg");
Where owl.jpg is an off-centre composition:
Gives this result:
First it shrinks the image to get the vertical axis to 128 pixels, then crops down to 128 pixels across using the attention strategy. This one searches the image for features which might catch a human eye, see Smartcrop() for details.
Why not use the System.Drawing.Image.GetThumbnailImage method?
public Image GetThumbnailImage(
int thumbWidth,
int thumbHeight,
Image.GetThumbnailImageAbort callback,
IntPtr callbackData)
Example:
Image originalImage = System.Drawing.Image.FromStream(inputStream, true, true);
Image resizedImage = originalImage.GetThumbnailImage(newWidth, (newWidth * originalImage.Height) / originalWidth, null, IntPtr.Zero);
resizedImage.Save(imagePath, ImageFormat.Png);
Source:
http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage.aspx
public static Image resizeImage(Image image, int new_height, int new_width)
{
Bitmap new_image = new Bitmap(new_width, new_height);
Graphics g = Graphics.FromImage((Image)new_image );
g.InterpolationMode = InterpolationMode.High;
g.DrawImage(image, 0, 0, new_width, new_height);
return new_image;
}
This will -
Resize width AND height without the need for a loop
Doesn't exceed the images original dimensions
//////////////
private void ResizeImage(Image img, double maxWidth, double maxHeight)
{
double resizeWidth = img.Source.Width;
double resizeHeight = img.Source.Height;
double aspect = resizeWidth / resizeHeight;
if (resizeWidth > maxWidth)
{
resizeWidth = maxWidth;
resizeHeight = resizeWidth / aspect;
}
if (resizeHeight > maxHeight)
{
aspect = resizeWidth / resizeHeight;
resizeHeight = maxHeight;
resizeWidth = resizeHeight * aspect;
}
img.Width = resizeWidth;
img.Height = resizeHeight;
}
This code is same as posted from one of above answers.. but will convert transparent pixel to white instead of black ... Thanks:)
public Image resizeImage(int newWidth, int newHeight, string stPhotoPath)
{
Image imgPhoto = Image.FromFile(stPhotoPath);
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
//Consider vertical pics
if (sourceWidth < sourceHeight)
{
int buff = newWidth;
newWidth = newHeight;
newHeight = buff;
}
int sourceX = 0, sourceY = 0, destX = 0, destY = 0;
float nPercent = 0, nPercentW = 0, nPercentH = 0;
nPercentW = ((float)newWidth / (float)sourceWidth);
nPercentH = ((float)newHeight / (float)sourceHeight);
if (nPercentH < nPercentW)
{
nPercent = nPercentH;
destX = System.Convert.ToInt16((newWidth -
(sourceWidth * nPercent)) / 2);
}
else
{
nPercent = nPercentW;
destY = System.Convert.ToInt16((newHeight -
(sourceHeight * nPercent)) / 2);
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(newWidth, newHeight,
PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.Clear(Color.White);
grPhoto.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
imgPhoto.Dispose();
return bmPhoto;
}
This is the code that I worked out for a specific requirement ie: the destination is always in landscape ratio. It should give you a good start.
public Image ResizeImage(Image source, RectangleF destinationBounds)
{
RectangleF sourceBounds = new RectangleF(0.0f,0.0f,(float)source.Width, (float)source.Height);
RectangleF scaleBounds = new RectangleF();
Image destinationImage = new Bitmap((int)destinationBounds.Width, (int)destinationBounds.Height);
Graphics graph = Graphics.FromImage(destinationImage);
graph.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
// Fill with background color
graph.FillRectangle(new SolidBrush(System.Drawing.Color.White), destinationBounds);
float resizeRatio, sourceRatio;
float scaleWidth, scaleHeight;
sourceRatio = (float)source.Width / (float)source.Height;
if (sourceRatio >= 1.0f)
{
//landscape
resizeRatio = destinationBounds.Width / sourceBounds.Width;
scaleWidth = destinationBounds.Width;
scaleHeight = sourceBounds.Height * resizeRatio;
float trimValue = destinationBounds.Height - scaleHeight;
graph.DrawImage(source, 0, (trimValue / 2), destinationBounds.Width, scaleHeight);
}
else
{
//portrait
resizeRatio = destinationBounds.Height/sourceBounds.Height;
scaleWidth = sourceBounds.Width * resizeRatio;
scaleHeight = destinationBounds.Height;
float trimValue = destinationBounds.Width - scaleWidth;
graph.DrawImage(source, (trimValue / 2), 0, scaleWidth, destinationBounds.Height);
}
return destinationImage;
}
In the application I made it was necessary to create a function with multiple options. It's quite large, but it resizes the image, can keep the aspect ratio and can cut of the edges to return only the center of the image:
/// <summary>
/// Resize image with a directory as source
/// </summary>
/// <param name="OriginalFileLocation">Image location</param>
/// <param name="heigth">new height</param>
/// <param name="width">new width</param>
/// <param name="keepAspectRatio">keep the aspect ratio</param>
/// <param name="getCenter">return the center bit of the image</param>
/// <returns>image with new dimentions</returns>
public Image resizeImageFromFile(String OriginalFileLocation, int heigth, int width, Boolean keepAspectRatio, Boolean getCenter)
{
int newheigth = heigth;
System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFileLocation);
// Prevent using images internal thumbnail
FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
if (keepAspectRatio || getCenter)
{
int bmpY = 0;
double resize = (double)FullsizeImage.Width / (double)width;//get the resize vector
if (getCenter)
{
bmpY = (int)((FullsizeImage.Height - (heigth * resize)) / 2);// gives the Y value of the part that will be cut off, to show only the part in the center
Rectangle section = new Rectangle(new Point(0, bmpY), new Size(FullsizeImage.Width, (int)(heigth * resize)));// create the section to cut of the original image
//System.Console.WriteLine("the section that will be cut off: " + section.Size.ToString() + " the Y value is minimized by: " + bmpY);
Bitmap orImg = new Bitmap((Bitmap)FullsizeImage);//for the correct effect convert image to bitmap.
FullsizeImage.Dispose();//clear the original image
using (Bitmap tempImg = new Bitmap(section.Width, section.Height))
{
Graphics cutImg = Graphics.FromImage(tempImg);// set the file to save the new image to.
cutImg.DrawImage(orImg, 0, 0, section, GraphicsUnit.Pixel);// cut the image and save it to tempImg
FullsizeImage = tempImg;//save the tempImg as FullsizeImage for resizing later
orImg.Dispose();
cutImg.Dispose();
return FullsizeImage.GetThumbnailImage(width, heigth, null, IntPtr.Zero);
}
}
else newheigth = (int)(FullsizeImage.Height / resize);// set the new heigth of the current image
}//return the image resized to the given heigth and width
return FullsizeImage.GetThumbnailImage(width, newheigth, null, IntPtr.Zero);
}
To make it easier to acces the function it's possible to add some overloaded functions:
/// <summary>
/// Resize image with a directory as source
/// </summary>
/// <param name="OriginalFileLocation">Image location</param>
/// <param name="heigth">new height</param>
/// <param name="width">new width</param>
/// <returns>image with new dimentions</returns>
public Image resizeImageFromFile(String OriginalFileLocation, int heigth, int width)
{
return resizeImageFromFile(OriginalFileLocation, heigth, width, false, false);
}
/// <summary>
/// Resize image with a directory as source
/// </summary>
/// <param name="OriginalFileLocation">Image location</param>
/// <param name="heigth">new height</param>
/// <param name="width">new width</param>
/// <param name="keepAspectRatio">keep the aspect ratio</param>
/// <returns>image with new dimentions</returns>
public Image resizeImageFromFile(String OriginalFileLocation, int heigth, int width, Boolean keepAspectRatio)
{
return resizeImageFromFile(OriginalFileLocation, heigth, width, keepAspectRatio, false);
}
Now are the last two booleans optional to set.
Call the function like this:
System.Drawing.Image ResizedImage = resizeImageFromFile(imageLocation, 800, 400, true, true);
public string CreateThumbnail(int maxWidth, int maxHeight, string path)
{
var image = System.Drawing.Image.FromFile(path);
var ratioX = (double)maxWidth / image.Width;
var ratioY = (double)maxHeight / image.Height;
var ratio = Math.Min(ratioX, ratioY);
var newWidth = (int)(image.Width * ratio);
var newHeight = (int)(image.Height * ratio);
var newImage = new Bitmap(newWidth, newHeight);
Graphics thumbGraph = Graphics.FromImage(newImage);
thumbGraph.CompositingQuality = CompositingQuality.HighQuality;
thumbGraph.SmoothingMode = SmoothingMode.HighQuality;
//thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
thumbGraph.DrawImage(image, 0, 0, newWidth, newHeight);
image.Dispose();
string fileRelativePath = "newsizeimages/" + maxWidth + Path.GetFileName(path);
newImage.Save(Server.MapPath(fileRelativePath), newImage.RawFormat);
return fileRelativePath;
}
Click here http://bhupendrasinghsaini.blogspot.in/2014/07/resize-image-in-c.html
If you're working with a BitmapSource:
var resizedBitmap = new TransformedBitmap(
bitmapSource,
new ScaleTransform(scaleX, scaleY));
If you want finer control over quality, run this first:
RenderOptions.SetBitmapScalingMode(
bitmapSource,
BitmapScalingMode.HighQuality);
(Default is BitmapScalingMode.Linear which is equivalent to BitmapScalingMode.LowQuality.)
Note: this will not work with ASP.Net Core because WebImage depends on System.Web, but on previous versions of ASP.Net I used this snippet many times and was useful.
String ThumbfullPath = Path.GetFileNameWithoutExtension(file.FileName) + "80x80.jpg";
var ThumbfullPath2 = Path.Combine(ThumbfullPath, fileThumb);
using (MemoryStream stream = new MemoryStream(System.IO.File.ReadAllBytes(fullPath)))
{
var thumbnail = new WebImage(stream).Resize(80, 80);
thumbnail.Save(ThumbfullPath2, "jpg");
}
Use below function with below example for changing image size :
//Example :
System.Net.Mime.MediaTypeNames.Image newImage = System.Net.Mime.MediaTypeNames.Image.FromFile("SampImag.jpg");
System.Net.Mime.MediaTypeNames.Image temImag = FormatImage(newImage, 100, 100);
//image size modification unction
public static System.Net.Mime.MediaTypeNames.Image FormatImage(System.Net.Mime.MediaTypeNames.Image img, int outputWidth, int outputHeight)
{
Bitmap outputImage = null;
Graphics graphics = null;
try
{
outputImage = new Bitmap(outputWidth, outputHeight, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
graphics = Graphics.FromImage(outputImage);
graphics.DrawImage(img, new Rectangle(0, 0, outputWidth, outputHeight),
new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);
return outputImage;
}
catch (Exception ex)
{
return img;
}
}
Resize and save an image to fit under width and height like a canvas keeping image proportional
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
namespace Infra.Files
{
public static class GenerateThumb
{
/// <summary>
/// Resize and save an image to fit under width and height like a canvas keeping things proportional
/// </summary>
/// <param name="originalImagePath"></param>
/// <param name="thumbImagePath"></param>
/// <param name="newWidth"></param>
/// <param name="newHeight"></param>
public static void GenerateThumbImage(string originalImagePath, string thumbImagePath, int newWidth, int newHeight)
{
Bitmap srcBmp = new Bitmap(originalImagePath);
float ratio = 1;
float minSize = Math.Min(newHeight, newHeight);
if (srcBmp.Width > srcBmp.Height)
{
ratio = minSize / (float)srcBmp.Width;
}
else
{
ratio = minSize / (float)srcBmp.Height;
}
SizeF newSize = new SizeF(srcBmp.Width * ratio, srcBmp.Height * ratio);
Bitmap target = new Bitmap((int)newSize.Width, (int)newSize.Height);
using (Graphics graphics = Graphics.FromImage(target))
{
graphics.CompositingQuality = CompositingQuality.HighSpeed;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.DrawImage(srcBmp, 0, 0, newSize.Width, newSize.Height);
using (MemoryStream memoryStream = new MemoryStream())
{
target.Save(thumbImagePath);
}
}
}
}
}
Below function will return the new size to display the image.This may not be helpful here.But it will return resized Display Rectangle size.
public static class ResizeImage
{
/// <summary>
/// Return new resized size to display the image
/// </summary>
/// <param name="srcrectanle">source rectangle of image or you can pass the bitmap and set the size accrodingly</param>
/// <param name="initSize">initial size of the page to draw image</param>
/// <returns></returns>
public static SizeF getResizedRectangle(RectangleF srcrectanle, SizeF initSize)
{
float sw = srcrectanle.Width;
float sh = srcrectanle.Height;
float dw = initSize.Width;
float dh = initSize.Height;
float finalHeight, finalWidth;
float Sourceratio = sw / sh;
if (Sourceratio >= 1)
{
finalWidth = (int)dw;
float ratio = sw / dw;
finalHeight = (sh / ratio);
}
else
{
finalHeight = (int)dh;
float ratio = sh / dh;
finalWidth = (sw / ratio);
}
return new SizeF(finalHeight, finalHeight);
}
}