Anyone knows of any good Image resize API for ASP.net?
Checkout System.Drawing Namespace
MSDN Documentation
Resizing Image - Stack Overflow Question
The ImageResizer library is actively developed, maintained, and supported (since 2007). It is up-to-date with the latest performance techniques, features, and has a simple API. It's safe, secure, reliable, and powers hundreds of commercial web sites.
It's compatible with ASP.NET 2.0 through 4.0, MVC, and is designed to be extremely fast with IIS 7.
Here's what I use:
internal static System.Drawing.Image FixedSize(System.Drawing.Image imgPhoto, int Width, int Height)
{
int sourceWidth = Convert.ToInt32(imgPhoto.Width);
int sourceHeight = Convert.ToInt32(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.Black);
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;
}
Usage is pretty simple:
System.Drawing.Image orignalImage = Image.FromFile(filePath);
System.Drawing.Image resizedImage = FixedSize(originalImage, 640, 480);
Resizing images is simple enough not to need an API. I wrote my own for this task. here's a bit if code to start you out down that path.
// get original image
System.Drawing.Image orignalImage = Image.FromFile(originalPath);
// create a new image at the desired size
System.Drawing.Bitmap newImage = new Bitmap(450, 338);
// create grpahics object to draw with
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(newImage);
//draw the new image
g.DrawImage(orignalImage, r);
// save the new image
newImage.Save(System.IO.Path.Combine(OUTPUT_FOLDER_PATH , ImageName.Replace(" ", "")));
I'll provide this as an alternative to the other answers provided. Image Magick is a very powerful and mature image processing library that you can use from .net. I've had a lot of success with it.
http://www.imagemagick.org/script/index.php
Here is a full image resizer sample application.
I have try myself and it work.
Sample Image Resizer
Image Resizer Class
Related
I know that standard WMF file uses an 18-byte header followed by GDI command records. A simple web search tells me that : "There are two additional WMF variations that place another header in front of the standard header. A Placeable Metafile uses a 22-byte header containing x-y coordinates for positioning the image on the page". but I kind of don't understaffed the real life application for such meta file type? What kind of requirements is this type supposed to address in comparison to the standard WMF?
Why am I interested? I have the following code for re-sizing and converting a WMF to GIF which fails at the point it tries to construct the bitmap out of the META file:
public Stream Resize(string filePath, int maxSize)
{
try
{
MemoryStream stream = new MemoryStream();
using (Metafile img = new Metafile(filePath))
{
MetafileHeader header = img.GetMetafileHeader();
float scale = header.DpiX / 96f;
var newSize = CalcaulateSize(img.Width, img.Height, maxSize);
using (Bitmap bitmap = new Bitmap((int)(scale * img.Width / header.DpiX * 100), (int)(scale * img.Height / header.DpiY * 100)))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.Clear(Color.White);
g.ScaleTransform(scale, scale);
g.DrawImage(img, 0, 0);
}
var resizedBitmap = new Bitmap(newSize.Width, newSize.Height);
using (var g2 = Graphics.FromImage(resizedBitmap))
{
g2.CompositingQuality = CompositingQuality.HighQuality;
g2.InterpolationMode = InterpolationMode.HighQualityBicubic;
g2.SmoothingMode = SmoothingMode.AntiAlias;
g2.PixelOffsetMode = PixelOffsetMode.HighQuality;
g2.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
g2.TextContrast = 12;
g2.Clear(Color.White);
g2.DrawImage(bitmap, 0, 0, newSize.Width, newSize.Height);
}
resizedBitmap.Save(stream, ImageFormat.Gif);
}
stream.Position = 0;
}
return stream;
}
catch (Exception)
{
return null;
}
and raises the exception "Argument is not valid".
(int)(scale * img.Width / header.DpiX * 100) = 22181
(int)(scale * img.Height / header.DpiY * 100)) = 33718
[too much memory to be allocated for a single bitmap all at once which results in immediate exception]
How would you alter the attached code to re-size and convert a place-able meta file?
I'd suspect that your size calculation is off.
Looking at my C++ code, I have this calculation based on the information in the enhanced metafile header where hEMF is the handle of the metafile. We then draw the image using a Graphics directly to the screen using those dimensions.
Hope this or the MSDN link helps a little. Sorry it's not more complete.
ENHMETAHEADER emh;
UINT nBytes = ::GetEnhMetaFileHeader(hEMF, sizeof(ENHMETAHEADER), &emh);
if (nBytes != 0) {
RECT rect{ // Based on info from http://support.microsoft.com/kb/230675
(int) ((float) (emh.rclFrame.left) * emh.szlDevice.cx / (emh.szlMillimeters.cx*100.0f)), // Left
(int) ((float) (emh.rclFrame.top) * emh.szlDevice.cy / (emh.szlMillimeters.cy*100.0f)), // Top
(int) ((float) (emh.rclFrame.right) * emh.szlDevice.cx / (emh.szlMillimeters.cx*100.0f)), // Right
(int) ((float) (emh.rclFrame.bottom) * emh.szlDevice.cy / (emh.szlMillimeters.cy*100.0f)) // Bottom
};
bounds.x = abs(rect.right - rect.left);
bounds.y = abs(rect.bottom - rect.top);
How to generate image as Thumb in simple way i think minimal coding on asp.net,
Then after how to save particular folder
I would not recommend to use the "Image.GetThumbnailImage" method because of the poor quality
(search "Image.GetThumbnailImage quality" on your favorite search engine...)
Here is a code snippet:
void GenerateThumbnail(string sourceImagePath, string destImagePath, int width, int height, System.Drawing.Imaging.ImageFormat destImageFormat)
{
using (var destImage = new System.Drawing.Bitmap(width, height))
{
using (var g = System.Drawing.Graphics.FromImage(destImage))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
using (var sourceImage = System.Drawing.Image.FromFile(sourceImagePath))
{
g.DrawImage(sourceImage, new System.Drawing.Rectangle(0, 0, width, height));
}
destImage.Save(destImagePath, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
OR - you can use Piczard (Piczard)
Here are some usage examples:
// 50% thumbnail (Jpeg image format)
var filter = new CodeCarvings.Piczard.ImageTransformation(50);
filter.SaveProcessedImageToFileSystem("~/MySourceImage.jpg", "~/MyDestImage.jpg");
// Fixed size thumbnail 400x200 (PNG image format)
var filter2 = new CodeCarvings.Piczard.FixedResizeConstraint(400, 200);
filter.SaveProcessedImageToFileSystem("~/MySourceImage2.jpg", "~/MyDestImage2.png");
I have tried like this so cool..!!,
public void ThumbGenerate(string sourcepath,string thumbsavepath, int width, int height)
{
Image image = Image.FromFile(sourcepath);
Image thumb = image.GetThumbnailImage(width, height, () => false, IntPtr.Zero);
thumb.Save(Path.ChangeExtension(thumbsavepath, "jpg"));
}
Note :You can change extension what you like something jpg,jpeg,png
i use this code to create thumbnails
System.Drawing.Image.GetThumbnailImageAbort abort = new System.Drawing.Image.GetThumbnailImageAbort(this.ThumbnailCallback);
System.Drawing.Image image2 = image.GetThumbnailImage((int)Math.Round((double)wid / difference), (int)Math.Round((double)hei / difference), abort, IntPtr.Zero);
image2.Save(str2, System.Drawing.Imaging.ImageFormat.Jpeg);
image2.Dispose();
but i get this very low quality image
but it is suposed to be like this one
what i am making wrong
or how can achieve this
Your problem is not really with the GetThumbnailImage() method, but instead in how you are saving the file. You need to specify the quality level of the JPEG you are saving, or it seems it always defaults to a very low value.
Consider this code as a guide (it's from an old .NET 2.0 project; the code still works fine compiled against 4.0, but there may be a more direct method in 4.0; I've never had reason to check)
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo jpegEncoder = null;
for (int x = 0; x < encoders.Length; x++) {
if (string.Compare(encoders[x].MimeType, "image/jpeg", true) == 0) {
jpegEncoder = encoders[x];
break;
}
}
if (jpegEncoder == null) throw new ApplicationException("Could not find JPEG encoder!");
EncoderParameters prms = new EncoderParameters(1);
prms.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 80L);
bitmap.Save(fileName, jpegEncoder, prms);
Here is another solution that should always work without fetching out the encoder. It resizes keeping relation between width & heigh ... modify for your needs.
/// <summary>
/// Resize an image with high quality
/// </summary>
public static Image ResizeImage(Image srcImage, int width)
{
var b = new Bitmap(width, srcImage.Height * width / srcImage.Width);
using (var g = Graphics.FromImage((Image)b))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(srcImage, 0, 0, b.Width, b.Height);
}
return b;
}
After searching, I've discovered this code:
Public Sub ResizeImage(ByVal scaleFactor As Double, ByVal fromStream As Stream, ByVal toStream As Stream)
Dim image__1 = System.Drawing.Image.FromStream(fromStream)
Dim newWidth = CInt(image__1.Width * scaleFactor)
Dim newHeight = CInt(image__1.Height * scaleFactor)
Dim thumbnailBitmap = New System.Drawing.Bitmap(newWidth, newHeight)
Dim thumbnailGraph = System.Drawing.Graphics.FromImage(thumbnailBitmap)
thumbnailGraph.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality
thumbnailGraph.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
thumbnailGraph.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
Dim imageRectangle = New System.Drawing.Rectangle(0, 0, newWidth, newHeight)
thumbnailGraph.DrawImage(image__1, imageRectangle)
thumbnailBitmap.Save(toStream, image__1.RawFormat)
thumbnailGraph.Dispose()
thumbnailBitmap.Dispose()
image__1.Dispose()
End Sub
There are 2 things I can't "modify" to solve my problem:
I wouldn't like to pass a stream, but I prefer to pass a path like C:\mysite\photo\myphoto.gif. How can I "convert" it to accept a file and not a stream?
In this function I've to pass a "scale" value. But I prefer to check if the image is too big (for example > 1024x768) than resize it to a max of 1024x768. How can I check this with System.Drawing.
As you can see I don't know anything about System.Drawing so I need an "hard" help to solve this job.
Here is some c# code I did about 5 years ago to do this (it should still work I hope as the app hasn't been touched since). I think it does everthing you need but it doesn't upscale the image to 1024x768 if it is smaller. This code will only make sure that if it is larger than 1024x768, it will resize proportionally to fit within those dimensions:
const int maxWidth = 1024;
const int maxHeight = 768;
Image newImage = Image.FromFile("YourPicture.jpg");
double percentToShrink = -1;
if (newImage.Width >= newImage.Height)
{
// Do we need to resize based on width?
if (newImage.Width > maxWidth)
{
percentToShrink = (double)maxWidth / (double)newImage.Width;
}
}
else
{
// Do we need to resize based on width?
if (newImage.Height > maxHeight )
{
percentToShrink = (double)maxHeight / (double)newImage.Height;
}
}
int newWidth = newImage.Width;
int newHeight = newImage.Height;
// So do we need to resize?
if (percentToShrink != -1)
{
newWidth = (int)(newImage.Width * percentToShrink);
newHeight = (int)(newImage.Height * percentToShrink);
}
// convert the image to a png and get a byte[]
MemoryStream imgStream = new MemoryStream();
Bitmap bmp = new Bitmap(newWidth, newHeight);
using (Graphics g = Graphics.FromImage(bmp))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.FillRectangle(System.Drawing.Brushes.White, 0, 0, newWidth, newHeight);
g.DrawImage(newImage, 0, 0, newWidth, newHeight);
}
// This can be whatever format you need
bmp.Save(imgStream, System.Drawing.Imaging.ImageFormat.Png);
byte[] imgBinaryData = imgStream.ToArray();
imgStream.Dispose();
If you need to convert this to VB.NET, you can use the C# to VB.NET converter here.
First question:
Dim newImage As Image = Image.FromFile("SampImag.jpg")
Second question:
Build a private method that will return you a Size object based on the original Size object of the given image. You can add a "keep proportions" flag also if you wish.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Story: The user uploads an image that will be added to a photo gallery. As part of the upload process, we need to A) store the image on the web server's hard drive and B) store a thumbnail of the image on the web server's hard drive.
"Best" here is defined as
Relatively easy to implement, understand, and maintain
Results in a thumbnail of reasonable quality
Performance and high-quality thumbnails are secondary.
GetThumbnailImage would work, but if you want a little better quality you can specify your image options for the BitMap class and save your loaded image into there. Here is some sample code:
Image photo; // your uploaded image
Bitmap bmp = new Bitmap(resizeToWidth, resizeToHeight);
graphic = Graphics.FromImage(bmp);
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;
graphic.DrawImage(photo, 0, 0, resizeToWidth, resizeToHeight);
imageToSave = bmp;
This provides better quality than GetImageThumbnail would out of the box
I suppose your best solution would be using the GetThumbnailImage from the .NET Image class.
// Example in C#, should be quite alike in ASP.NET
// Assuming filename as the uploaded file
using ( Image bigImage = new Bitmap( filename ) )
{
// Algorithm simplified for purpose of example.
int height = bigImage.Height / 10;
int width = bigImage.Width / 10;
// Now create a thumbnail
using ( Image smallImage = image.GetThumbnailImage( width,
height,
new Image.GetThumbnailImageAbort(Abort), IntPtr.Zero) )
{
smallImage.Save("thumbnail.jpg", ImageFormat.Jpeg);
}
}
Using an example above and some from a couple of other places, here is an easy function to just drop in (thanks to Nathanael Jones and others here).
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
public static void ResizeImage(string FileNameInput, string FileNameOutput, double ResizeHeight, double ResizeWidth, ImageFormat OutputFormat)
{
using (System.Drawing.Image photo = new Bitmap(FileNameInput))
{
double aspectRatio = (double)photo.Width / photo.Height;
double boxRatio = ResizeWidth / ResizeHeight;
double scaleFactor = 0;
if (photo.Width < ResizeWidth && photo.Height < ResizeHeight)
{
// keep the image the same size since it is already smaller than our max width/height
scaleFactor = 1.0;
}
else
{
if (boxRatio > aspectRatio)
scaleFactor = ResizeHeight / photo.Height;
else
scaleFactor = ResizeWidth / photo.Width;
}
int newWidth = (int)(photo.Width * scaleFactor);
int newHeight = (int)(photo.Height * scaleFactor);
using (Bitmap bmp = new Bitmap(newWidth, newHeight))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawImage(photo, 0, 0, newWidth, newHeight);
if (ImageFormat.Png.Equals(OutputFormat))
{
bmp.Save(FileNameOutput, OutputFormat);
}
else if (ImageFormat.Jpeg.Equals(OutputFormat))
{
ImageCodecInfo[] info = ImageCodecInfo.GetImageEncoders();
EncoderParameters encoderParameters;
using (encoderParameters = new System.Drawing.Imaging.EncoderParameters(1))
{
// use jpeg info[1] and set quality to 90
encoderParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L);
bmp.Save(FileNameOutput, info[1], encoderParameters);
}
}
}
}
}
}
Here is an extension method in VB.NET for the Image Class
Imports System.Runtime.CompilerServices
Namespace Extensions
''' <summary>
''' Extensions for the Image class.
''' </summary>
''' <remarks>Several usefull extensions for the image class.</remarks>
Public Module ImageExtensions
''' <summary>
''' Extends the image class so that it is easier to get a thumbnail from an image
''' </summary>
''' <param name="Input">Th image that is inputted, not really a parameter</param>
''' <param name="MaximumSize">The maximumsize the thumbnail must be if keepaspectratio is set to true then the highest number of width or height is used and the other is calculated accordingly. </param>
''' <param name="KeepAspectRatio">If set false width and height will be the same else the highest number of width or height is used and the other is calculated accordingly.</param>
''' <returns>A thumbnail as image.</returns>
''' <remarks>
''' <example>Can be used as such.
''' <code>
''' Dim _NewImage as Image
''' Dim _Graphics As Graphics
''' _Image = New Bitmap(100, 100)
''' _Graphics = Graphics.FromImage(_Image)
''' _Graphics.FillRectangle(Brushes.Blue, New Rectangle(0, 0, 100, 100))
''' _Graphics.DrawLine(Pens.Black, 10, 0, 10, 100)
''' Assert.IsNotNull(_Image)
''' _NewImage = _Image.ToThumbnail(10)
''' </code>
''' </example>
''' </remarks>
<Extension()> _
Public Function ToThumbnail(ByVal Input As Image, ByVal MaximumSize As Integer, Optional ByVal KeepAspectRatio As Boolean = True) As Image
Dim ReturnImage As Image
Dim _Callback As Image.GetThumbnailImageAbort = Nothing
Dim _OriginalHeight As Double
Dim _OriginalWidth As Double
Dim _NewHeight As Double
Dim _NewWidth As Double
Dim _NormalImage As Image
Dim _Graphics As Graphics
_NormalImage = New Bitmap(Input.Width, Input.Height)
_Graphics = Graphics.FromImage(_NormalImage)
_Graphics.DrawImage(Input, 0, 0, Input.Width, Input.Height)
_OriginalHeight = _NormalImage.Height
_OriginalWidth = _NormalImage.Width
If KeepAspectRatio = True Then
If _OriginalHeight > _OriginalWidth Then
If _OriginalHeight > MaximumSize Then
_NewHeight = MaximumSize
_NewWidth = _OriginalWidth / _OriginalHeight * MaximumSize
Else
_NewHeight = _OriginalHeight
_NewWidth = _OriginalWidth
End If
Else
If _OriginalWidth > MaximumSize Then
_NewWidth = MaximumSize
_NewHeight = _OriginalHeight / _OriginalWidth * MaximumSize
Else
_NewHeight = _OriginalHeight
_NewWidth = _OriginalWidth
End If
End If
Else
_NewHeight = MaximumSize
_NewWidth = MaximumSize
End If
ReturnImage = _
_NormalImage.GetThumbnailImage(Convert.ToInt32(_NewWidth), Convert.ToInt32(_NewHeight), _Callback, _
IntPtr.Zero)
_NormalImage.Dispose()
_NormalImage = Nothing
_Graphics.Dispose()
_Graphics = Nothing
_Callback = Nothing
Return ReturnImage
End Function
End Module
End Namespace
Sorry the code tag doesn't like vb.net code.
You can use the Image.GetThumbnailImage function to do it for you.
http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage.aspx (.NET 3.5)
http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage(VS.80).aspx (.NET 2.0)
public bool ThumbnailCallback()
{
return false;
}
public void Example_GetThumb(PaintEventArgs e)
{
Image.GetThumbnailImageAbort myCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);
Bitmap myBitmap = new Bitmap("Climber.jpg");
Image myThumbnail = myBitmap.GetThumbnailImage(40, 40, myCallback, IntPtr.Zero);
e.Graphics.DrawImage(myThumbnail, 150, 75);
}
Avoid GetThumbnailImage - it will provide very unpredictable results, since it tries to use the embedded JPEG thumbnail if available - even if the embedded thumbnail is entirely the wrong size. DrawImage() is a much better solution.
Wrap your bitmap in a using{} clause - you don't want leaked handles floating around...
Also, you'll want to set your Jpeg encoding quality to 90, which is where GDI+ seems to shine the best:
System.Drawing.Imaging.ImageCodecInfo[] info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
System.Drawing.Imaging.EncoderParameters encoderParameters;
encoderParameters = new System.Drawing.Imaging.EncoderParameters(1);
encoderParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L);
thumb.Save(ms, info[1], encoderParameters);