This question already has answers here:
Resize image proportionally with MaxHeight and MaxWidth constraints
(3 answers)
Closed 9 years ago.
Am re sizing an image with the following code
using (Image thumbnail = new Bitmap(100, 50))
{
using (Bitmap source = new Bitmap(imageFile))
{
using (Graphics g = Graphics.FromImage(thumbnail))
{
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(source, 0, 0, 100, 50);
}
}
using (MemoryStream ms = new MemoryStream())
{
thumbnail.Save(ms, ImageFormat.Png);
thumbnail.Save(dest, ImageFormat.Png);
}
}
but it is not giving an image of any quality. pixelation is making the image wired.
i have also tried the code
image re size in stack
but am getting a black screen as the result instead of jpg am using png is the only difference.
any suggestion for improving the image quality. i have to re size the transparent image to a size 100by50.
Thanks in advance.
Try this, Assuming you can use it
public static Image Resize(Image originalImage, int w, int h)
{
//Original Image attributes
int originalWidth = originalImage.Width;
int originalHeight = originalImage.Height;
// Figure out the ratio
double ratioX = (double)w / (double)originalWidth;
double ratioY = (double)h / (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);
Image thumbnail = new Bitmap(newWidth, newHeight);
Graphics graphic = Graphics.FromImage(thumbnail);
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;
graphic.Clear(Color.Transparent);
graphic.DrawImage(originalImage, 0, 0, newWidth, newHeight);
return thumbnail;
}
Related
I have a form without border and need show only a image in the corner of window, the picture dimentions are 9567 x 18012 and size is 62 MB, i use a PictureBox in a form when resize the quality loss, why?, i a need a thirdparty library for show a image to big in dimensions and size?
The left image is a PictureBox with my image and the right is the original image with te information
Use the following code to reduce the image size.
public void SetPictureBoxImage(string path)
{
Image myImage = Image.FromFile(path, true);
int width = 500;
double ratio = (double)myImage.Width / (double)myImage.Height;
int height = Convert.ToInt32(width / ratio);
if (height > width)
{
ratio = (double)myImage.Height / (double)myImage.Width;
height = width;
width = Convert.ToInt32(height / ratio);
}
pictureBox1.Image = ResizeImage(myImage, width, height);
}
Resize Method
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);
}
}
return destImage;
}
I want resize an Image for fit a size (width and height) without stretch the original image.
My code, resize the image to the specified size but stretch the original image.
this is the code:
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.Tile);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
So you want to Scale with respect to Aspect Ratio.
What we should do is to get a factor and resize both width and height by that factor.
And we need not to go above desired width and height (that's why we use Math.Min on both width and height ratios).
double oldWidth = image.Width;
double oldHeight = image.Height;
var widthRatio = width / oldWidth;
var heightRatio = height / oldHeight;
var factor = Math.Min(widthRatio, heightRatio);
and here we use it like this:
var destRect = new Rectangle(0, 0, (int)(factor * oldWidth), (int)(factor * oldHeight));
Following this question Resize image proportionally with MaxHeight and MaxWidth constraints
I implemented the solution as follows:
public static class ImageResizer
{
public static Image ResizeImage(String origFileLocation, int maxWidth, int maxHeight)
{
Image img = Image.FromFile(origFileLocation);
if (img.Height < maxHeight && img.Width < maxWidth) return img;
using (img)
{
Double xRatio = (double)maxWidth / img.Width;
Double yRatio = (double)maxHeight / img.Height;
Double ratio = Math.Max(xRatio, yRatio);
int nnx = (int)Math.Floor(img.Width * ratio);
int nny = (int)Math.Floor(img.Height * ratio);
Bitmap cpy = new Bitmap(nnx, nny, PixelFormat.Format32bppArgb);
using (Graphics gr = Graphics.FromImage(cpy))
{
gr.Clear(Color.Transparent);
// This is said to give best quality when resizing images
gr.SmoothingMode = SmoothingMode.HighQuality;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.DrawImage(img,
new Rectangle(0, 0, nnx, nny),
new Rectangle(0, 0, img.Width, img.Height),
GraphicsUnit.Pixel);
}
return cpy;
}
}
}
And then saving image this way:
resized.Save(resizedFilePath, System.Drawing.Imaging.ImageFormat.Gif);
However, trying it, shrinking image, the result is very grained as you can see in this photo
I would assume that shrinking image should result with no noticeable effects. Any ideas about it?
Yes. As #Ivan Stoev suggested. The problem is not with the resizing, rather in the saving method which appears to compress the image by default for some reason.
I used
resized.Save(resizedFilePath, System.Drawing.Imaging.ImageFormat.Png);
for saving and now everything seems fine. Thank you.
resized.Save(resizedFilePath, System.Drawing.Imaging.ImageFormat.Png);
size large not optimation
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I get better results when shrinking an image
I am trying to generate a thumbnail of size 200 x 200px using the code below. It works fine for certain images but does not for others. When it does not work, the thumbnail is generated with that size but only partial image is seen and the other part is gray (like you have used a gray brush and smeared on top of the thumbnail). I haven't been able to see a trend when it fails. For example, it fails for a JPEG image with 400px x 400px size. If I try to generate the thumbnail with size 150px x 150px, there is no image loss.
If this helps here is one image that causes problems - http://s11.postimage.org/sse5zhpqr/Drawing_8.jpg
Appreciate your time.
public Bitmap GenerateThumbnail(Bitmap sourceBitmap, int thumbnailWidth, int thumbnailHeight)
{
Bitmap thumbnailBitmap = null;
decimal ratio;
int newWidth = 0;
int newHeight = 0;
// If the image is smaller than the requested thumbnail size just return it
if (sourceBitmap.Width < thumbnailWidth &&
sourceBitmap.Height < thumbnailHeight)
{
newWidth = sourceBitmap.Width;
newHeight = sourceBitmap.Height;
}
else if (sourceBitmap.Width > sourceBitmap.Height)
{
ratio = (decimal)thumbnailWidth / sourceBitmap.Width;
newWidth = thumbnailWidth;
decimal tempDecimalHeight = sourceBitmap.Height * ratio;
newHeight = (int)tempDecimalHeight;
}
else
{
ratio = (decimal)thumbnailHeight / sourceBitmap.Height;
newHeight = thumbnailHeight;
decimal tempDecimalHeight = sourceBitmap.Width * ratio;
newWidth = (int)tempDecimalHeight;
}
thumbnailBitmap = new Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage(thumbnailBitmap);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.FillRectangle(Brushes.White, 0, 0, newWidth, newHeight);
g.DrawImage(sourceBitmap, 0, 0, newWidth, newHeight);
g.Dispose();
return thumbnailBitmap;
}
Update:
I did some more analysis and it seems that the issue is while saving the thumbnail to the SQL Server database in a varbinary column. I am using a MemoryStream to do that as below. If I save it to the disk it appears just fine. Here is my thumbnail from the database - http://s12.postimage.org/a7j50vr8d/Generated_Thumbnail.jpg
using (MemoryStream thumbnailStream = new MemoryStream())
{
thumbnailBitmap.Save(thumbnailStream, System.Drawing.Imaging.ImageFormat.Jpeg);
return thumbnailStream.ToArray();
}
Update - This problem is resolved. The issue was NHibernate mapping that I was using for the varbinary column. I had to specify the type as "BinaryBlob" to make sure there is no silent truncation of data > 8KB.
I appreciate, this should probably be a comment and not an answer, but for the extra formatting I'm posting as an answer.
Here's the code I've used to shrink an image and I've never had this issue:
private byte[] ResizeImage(System.Drawing.Image image, double scaleFactor)
{
//a holder for the result
int newWidth = (int)(image.Width * scaleFactor);
int newHeight = (int)(image.Height * scaleFactor);
Bitmap result = new Bitmap(newWidth, newHeight);
//use a graphics object to draw the resized image into the bitmap
using (Graphics graphics = Graphics.FromImage(result))
{
//set the resize quality modes to high quality
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//draw the image into the target bitmap
graphics.DrawImage(image, 0, 0, result.Width, result.Height);
}
//return the resulting bitmap
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(result, typeof(byte[]));
}
Granted, I return a byte[] and not a Bitmap, as I then save it to a database.
The only differences I can really see is that instantiate my result Bitmap with a height and width, I have no call to the FillRectangle method, and I do not set the PixelOffsetMode. I also start off with an Image instead of a Bitmap
Hope this helps you somehow though.
Problem:
I found this function here a few days ago but I couldn't find it again. It resizes images but the output quality is not good. It looks like the color depth is 8 bit.
First photo is the original, 2nd is Photoshopped and the last one is resized by the code:
Samples:
Function:
Image ResizeImage(Image original, int targetWidth)
{
double percent = (double)original.Width / targetWidth;
int destWidth = (int)(original.Width / percent);
int destHeight = (int)(original.Height / percent);
Bitmap b = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage((Image)b);
try
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(original, 0, 0, destWidth, destHeight);
}
finally
{
g.Dispose();
}
return (Image)b;
}
Looks like the image being transformed to indexed-color pixel format at some stage. Check this article and try to set up PixelFormat and Resolution properties explicitly.