Performance optimization of multiple rotating images - c#

I'm working on a project in C# windows forms where I'm using pictureboxes to display multiple tachometers.
Each picturebox consists of a background image and an image. The background image is static, but the image (displaying the actual indicator) is rotated and updated a couple of times per second.
Background image: http://i.stack.imgur.com/FBsKI.jpg
Fron image: http://i.stack.imgur.com/T0nJU.jpg
It works well as long as I have one or two tachometers running simultaneously, but when I add more it starts to lag a lot.
Here is the code I use for updating the picturebox:
private void timer4_Tick(object sender, EventArgs e)
{
Bitmap image = RotateImage(indicatorImg, i++, false, true, Color.Transparent);
pictureBox4.Image = image;
}
The RotateImage function I'm using (Credit to RenniePet at https://stackoverflow.com/a/16027561/3660713):
public static Bitmap RotateImage(Image inputImage, float angleDegrees, bool upsizeOk,
bool clipOk, Color backgroundColor)
{
lock (lockObject)
{
// Test for zero rotation and return a clone of the input image
if (angleDegrees == 0f)
return (Bitmap)inputImage.Clone();
// Set up old and new image dimensions, assuming upsizing not wanted and clipping OK
int oldWidth = inputImage.Width;
int oldHeight = inputImage.Height;
int newWidth = oldWidth;
int newHeight = oldHeight;
float scaleFactor = 1f;
// If upsizing wanted or clipping not OK calculate the size of the resulting bitmap
if (upsizeOk || !clipOk)
{
double angleRadians = angleDegrees * Math.PI / 180d;
double cos = Math.Abs(Math.Cos(angleRadians));
double sin = Math.Abs(Math.Sin(angleRadians));
newWidth = (int)Math.Round(oldWidth * cos + oldHeight * sin);
newHeight = (int)Math.Round(oldWidth * sin + oldHeight * cos);
}
// If upsizing not wanted and clipping not OK need a scaling factor
if (!upsizeOk && !clipOk)
{
scaleFactor = Math.Min((float)oldWidth / newWidth, (float)oldHeight / newHeight);
newWidth = oldWidth;
newHeight = oldHeight;
}
// Create the new bitmap object. If background color is transparent it must be 32-bit,
// otherwise 24-bit is good enough.
Bitmap newBitmap = new Bitmap(newWidth, newHeight, backgroundColor == Color.Transparent ?
PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb);
newBitmap.SetResolution(inputImage.HorizontalResolution, inputImage.VerticalResolution);
// Create the Graphics object that does the work
using (Graphics graphicsObject = Graphics.FromImage(newBitmap))
{
graphicsObject.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphicsObject.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
graphicsObject.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
// Fill in the specified background color if necessary
if (backgroundColor != Color.Transparent)
graphicsObject.Clear(backgroundColor);
// Set up the built-in transformation matrix to do the rotation and maybe scaling
graphicsObject.TranslateTransform(newWidth / 2f, newHeight / 2f);
if (scaleFactor != 1f)
graphicsObject.ScaleTransform(scaleFactor, scaleFactor);
graphicsObject.RotateTransform(angleDegrees);
graphicsObject.TranslateTransform(-oldWidth / 2f, -oldHeight / 2f);
// Draw the result
graphicsObject.DrawImage(inputImage, 0, 0);
}
return newBitmap;
}
}
Any ideas on how to improve performance? Is there a better way to do this?

I would create a static list of images for each angle of degrees required on startup.
You could then reference the correct index in the list and use that pre rotated image.

Thank you for your help!
What I did was that I added a WPF control to my Winforms project. The WPF control contains the two images and simply contains code for rotating the front image:
C#:
public void Rotate(float deg)
{
RotateTransform rt = new RotateTransform(deg);
image2.RenderTransform = rt;
}
XAML:
<UserControl x:Class="Project.WPF_imgControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Image HorizontalAlignment="Left" Name="image1" Stretch="Fill" VerticalAlignment="Top" Source="/Project;component/Images/Tachometer.png" />
<Image RenderTransformOrigin =".5,.5" HorizontalAlignment="Left" Name="image2" Stretch="Fill" VerticalAlignment="Top" Source="/Project;component/Images/Pointer_80%25.png" />
</Grid>
Now I just have to find out why the image looks jagged in the WPF component compared to my standard form.
Edit: RenderOptions.BitmapScalingMode="HighQuality" did the trick :)
//Jocke

Related

Crop correct part of image while the PictureBox is in 'zoom' mode [duplicate]

This question already has an answer here:
Draw Rectangle inside picture box SizeMode Zoom
(1 answer)
Closed 3 years ago.
I have a PictureBox1 with it's sizemode set to Stretch and PictureBox1. The PictureBox1 contains an image and let's me select part of it and then crop it and store the cropped part inside PictureBox2. It works great when the sizemode is set to Stretch and the picture is not zoomed, but not when I zoom it or set the sizemode to zoom.
working example - sizemode set to 'stretch'
The code I use to crop part of the picture (original source)
try
{
float stretch1X = 1f * pictureBox1.Image.Width / pictureBox1.ClientSize.Width;
float stretch1Y = 1f * pictureBox1.Image.Height / pictureBox1.ClientSize.Height;
Point pt = new Point((int)(_mDown.X * stretch1X), (int)(_mDown.Y * stretch1Y));
Size sz = new Size((int)((_mCurr.X - _mDown.X) * stretch1X),
(int)((_mCurr.Y - _mDown.Y) * stretch1Y));
if (sz.Width > 0 && sz.Height > 0)
{
Rectangle rSrc = new Rectangle(pt, sz);
Rectangle rDest = new Rectangle(Point.Empty, sz);
Bitmap bmp = new Bitmap(sz.Width, sz.Height);
using (Graphics G = Graphics.FromImage(bmp))
G.DrawImage(pictureBox1.Image, rDest, rSrc, GraphicsUnit.Pixel);
return bmp;
}
return null;
}
catch (Exception ex)
{
throw ex;
}
How do I calculate it properly? How can I make the crop function work in a way so it lets the user zoom in/out and still crop the correct part of the picture?
You need to calculate the points using the stretch factor and maybe also the offset.
For Zoom there is only one factor as aspect ratio is always the same for Image and PictureBox, but there usually is an offset; for Stretch you need no offset but two factors.
Here is an example that goes all the way using two PictureBoxes two show a zoomed version and the cropped bitmap. It makes use of an all-purpose function ImageArea that determines size and offset.
Two class level variables:
Point pDown = Point.Empty;
Rectangle rect = Rectangle.Empty;
Three mouse events:
private void PictureBox1_MouseDown(object sender, MouseEventArgs e)
{
pDown = e.Location;
pictureBox1.Refresh();
}
private void PictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (!e.Button.HasFlag(MouseButtons.Left)) return;
rect = new Rectangle(pDown, new Size(e.X - pDown.X, e.Y - pDown.Y));
using (Graphics g = pictureBox1.CreateGraphics())
{
pictureBox1.Refresh();
g.DrawRectangle(Pens.Orange, rect);
}
}
private void PictureBox1_MouseUp(object sender, MouseEventArgs e)
{
Rectangle iR = ImageArea(pictureBox2);
rect = new Rectangle(pDown.X - iR.X, pDown.Y - iR.Y,
e.X - pDown.X, e.Y - pDown.Y);
Rectangle rectSrc = Scaled(rect, pictureBox2, true);
Rectangle rectDest = new Rectangle(Point.Empty, rectSrc.Size);
Bitmap bmp = new Bitmap(rectDest.Width, rectDest.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawImage(pictureBox2.Image, rectDest, rectSrc, GraphicsUnit.Pixel);
}
pictureBox2.Image = bmp;
}
Here is a useful function that returns the area of the actual image inside a picturebox for any sizemode..:
Rectangle ImageArea(PictureBox pbox)
{
Size si = pbox.Image.Size;
Size sp = pbox.ClientSize;
if (pbox.SizeMode == PictureBoxSizeMode.StretchImage)
return pbox.ClientRectangle;
if (pbox.SizeMode == PictureBoxSizeMode.Normal ||
pbox.SizeMode == PictureBoxSizeMode.AutoSize)
return new Rectangle(Point.Empty, si);
if (pbox.SizeMode == PictureBoxSizeMode.CenterImage)
return new Rectangle(new Point((sp.Width - si.Width) / 2,
(sp.Height - si.Height) / 2), si);
// PictureBoxSizeMode.Zoom
float ri = 1f * si.Width / si.Height;
float rp = 1f * sp.Width / sp.Height;
if (rp > ri)
{
int width = si.Width * sp.Height / si.Height;
int left = (sp.Width - width) / 2;
return new Rectangle(left, 0, width, sp.Height);
}
else
{
int height = si.Height * sp.Width / si.Width;
int top = (sp.Height - height) / 2;
return new Rectangle(0, top, sp.Width, height);
}
}
We only need the offset to determine the rectangle unscaled. We also need to scale it:
Rectangle Scaled(Rectangle rect, PictureBox pbox, bool scale)
{
float factor = GetFactor(pbox);
if (!scale) factor = 1f / factor;
return Rectangle.Round(new RectangleF(rect.X * factor, rect.Y * factor,
rect.Width * factor, rect.Height * factor));
}
For this need to know the scaling factor, which depends on the aspect ratio:
float GetFactor(PictureBox pBox)
{
if (pBox.Image == null) return 0;
Size si = pBox.Image.Size;
Size sp = pBox.ClientSize;
float ri = 1f * si.Width / si.Height;
float rp = 1f * sp.Width / sp.Height;
float factor = 1f * pBox.Image.Width / pBox.ClientSize.Width;
if (rp > ri) factor = 1f * pBox.Image.Height / pBox.ClientSize.Height;
return factor;
}
This solution will also work if the PictureBox is zoomed in or out by placing it inside a AutoScrolling Panel and changing the Pbox.Size.

Strange behavior of ZXing.Net when reading a barcode

My code:
IBarcodeReaderGeneric reader = new BarcodeReaderGeneric()
{
AutoRotate = true,
TryInverted = true,
Options =
{
PossibleFormats = new List<BarcodeFormat> { BarcodeFormat.CODE_39 },
TryHarder = true,
ReturnCodabarStartEnd = true,
PureBarcode = false
}
};
Getting a barcode:
using (var img = RotateImage(newBitmap, -90, true, true, Color.White))
{
lum = new BitmapLuminanceSource(img);
barcode = reader.Decode(lum)?.ToString();
if (!string.IsNullOrEmpty(barcode))
{
return img;
}
}
The method that rotates the image:
public static Bitmap RotateImage(Image inputImage, float angleDegrees, bool upsizeOk,
bool clipOk, Color backgroundColor)
{
// Test for zero rotation and return a clone of the input image
if (angleDegrees == 0f)
return (Bitmap)inputImage.Clone();
// Set up old and new image dimensions, assuming upsizing not wanted and clipping OK
int oldWidth = inputImage.Width;
int oldHeight = inputImage.Height;
int newWidth = oldWidth;
int newHeight = oldHeight;
float scaleFactor = 1f;
// If upsizing wanted or clipping not OK calculate the size of the resulting bitmap
if (upsizeOk || !clipOk)
{
double angleRadians = angleDegrees * Math.PI / 180d;
double cos = Math.Abs(Math.Cos(angleRadians));
double sin = Math.Abs(Math.Sin(angleRadians));
newWidth = (int)Math.Round(oldWidth * cos + oldHeight * sin);
newHeight = (int)Math.Round(oldWidth * sin + oldHeight * cos);
}
// If upsizing not wanted and clipping not OK need a scaling factor
if (!upsizeOk && !clipOk)
{
scaleFactor = Math.Min((float)oldWidth / newWidth, (float)oldHeight / newHeight);
newWidth = oldWidth;
newHeight = oldHeight;
}
// Create the new bitmap object. If background color is transparent it must be 32-bit,
// otherwise 24-bit is good enough.
Bitmap newBitmap = new Bitmap(newWidth, newHeight, backgroundColor == Color.Transparent ?
PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb);
newBitmap.SetResolution(inputImage.HorizontalResolution, inputImage.VerticalResolution);
// Create the Graphics object that does the work
using (Graphics graphicsObject = Graphics.FromImage(newBitmap))
{
graphicsObject.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphicsObject.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphicsObject.SmoothingMode = SmoothingMode.HighQuality;
// Fill in the specified background color if necessary
if (backgroundColor != Color.Transparent)
graphicsObject.Clear(backgroundColor);
// Set up the built-in transformation matrix to do the rotation and maybe scaling
graphicsObject.TranslateTransform(newWidth / 2f, newHeight / 2f);
if (scaleFactor != 1f)
graphicsObject.ScaleTransform(scaleFactor, scaleFactor);
graphicsObject.RotateTransform(angleDegrees);
graphicsObject.TranslateTransform(-oldWidth / 2f, -oldHeight / 2f);
// Draw the result
graphicsObject.DrawImage(inputImage, 0, 0);
}
I'm trying to read a barcode from a scanned image that is rotated 90 degrees. I use the standard code to rotate the image, the code is read from this image:
note which large spaces on the top and bottom, you can get them if you call the method in the following way: RotateImage(newBitmap, -90, false, false, Color.White)
But if the image is rotated as positively, as in the picture:
then the bar code can not be read! Why is this happening? After all, the second image is correctly rotated, unlike the first one.
I want to advise you to work with Spire.Barcode, it is also free of charge and does a much better job of its task. With her, I had no problems.

Scaling and rotating images in C# results in ghosted edges

I'm using C# to scale and rotate an image with a transparent background, then using JavaScript to add it to a Google Maps API map, but once it's scaled and rotated, the edges of the image get blurred, and it becomes hard to see, especially over water.
Here is my original 300x300 image:
And here is an example of one of the output images at 100x100 (SizeInt = 100):
Before you get confused as to the background colour, the image is projected onto a map where the water is a similar colour to the image.
You can see some slight ghosting around the edges of the image.
Once it's scaled down further (to it's required scale):
It's almost unnoticeable...
I'm still relatively new to C#, but I've tried loading SVGs directly onto the map with JavaScript (icon: "some/SVG/file.svg"), but that causes serious performance problems, as there are up to 1,000 icons on the map at any given time, making the map unusable when using SVG files, so I have to use image files.
The images need to be sharp and not blurred around the edges. Here is the code used to generate the images, forgive any sloppy code, I'm still somewhat new to C#:
Here is the code used to scale the image:
The image needs to be rotated in a full circle (rounded to 5 degrees), hence the loop from 0 to 361.
private void BuildIcons(string dir)
{
int SizeInt = 30;
// Get the content path
var ContentPath = dir;
// Get the original image
Bitmap OriginalImage = new Bitmap(ContentPath + "base.png");
#region Resize image
// New size
Size size = new Size(SizeInt, SizeInt);
// New height/width temp vars
int newWidth;
int newHeight;
// Aspect ratio preservation
int originalWidth = OriginalImage.Width;
int originalHeight = OriginalImage.Height;
float percentWidth = (float)size.Width / (float)originalWidth;
float percentHeight = (float)size.Height / (float)originalHeight;
float percent = percentHeight < percentWidth ? percentHeight : percentWidth;
newWidth = (int)(originalWidth * percent);
newHeight = (int)(originalHeight * percent);
// Generate the new image
Image ResizedImage = new Bitmap(newWidth, newHeight);
using (Graphics graphicsHandle = Graphics.FromImage(ResizedImage))
{
graphicsHandle.SmoothingMode = SmoothingMode.HighQuality;
graphicsHandle.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphicsHandle.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphicsHandle.DrawImage(OriginalImage, 0, 0, newWidth, newHeight);
}
#endregion
int maxside = SizeInt;
#region Image rotation
// Generate images
for (int i = 0; i < 361; i += 5)
{
// New empty bitmap to hold rotated images
Bitmap ReturnBitmap = new Bitmap(maxside, maxside);
// Graphics object from the empty bitmap
// Normal
Graphics Gfx = Graphics.FromImage(ReturnBitmap);
Gfx.SmoothingMode = SmoothingMode.HighQuality;
Gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
Gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
// Move rotation point to center of image
Gfx.TranslateTransform(
(float)ResizedImage.Width / 2,
(float)ResizedImage.Height / 2
);
// Rotate
Gfx.RotateTransform(i);
// Move image back
Gfx.TranslateTransform(
-(float)ResizedImage.Width / 2,
-(float)ResizedImage.Height / 2
);
// draw original in image onto graphics object
Gfx.DrawImage(ResizedImage, new Point(0, 0));
// Save the image
ReturnBitmap.Save(ContentPath + i.ToString() + ".png");
// Clean up
ReturnBitmap.Dispose();
Gfx.Dispose();
}
#endregion
// Clean up
ResizedImage.Dispose();
OriginalImage.Dispose();
}
Any suggestions?

File Size of an Image Increases close to 10 times after Rotating it to a particular angle

I am trying to rotate a image after scanning to improve the readability of scanned images if the skew angle is too high. After finding out the Deskew angle i am trying to rotate the image with the following Code.
After rotating the image and saving it subsequently , my image size is increase closed to 10 times.
What is the reason for the increase in the File Size of an image ?
public Bitmap RotateImage(Image inputImage, float angleDegrees, bool upsizeOk,
bool clipOk, Color backgroundColor)
{
/// Method to rotate an Image object. The result can be one of three cases:
/// - upsizeOk = true: output image will be larger than the input, and no clipping occurs
/// - upsizeOk = false & clipOk = true: output same size as input, clipping occurs
/// - upsizeOk = false & clipOk = false: output same size as input, image reduced, no clipping
///
// Test for zero rotation and return a clone of the input image
if (angleDegrees == 0f)
return (Bitmap)inputImage.Clone();
// Set up old and new image dimensions, assuming upsizing not wanted and clipping OK
int oldWidth = inputImage.Width;
int oldHeight = inputImage.Height;
int newWidth = oldWidth;
int newHeight = oldHeight;
float scaleFactor = 1f;
// If upsizing wanted or clipping not OK calculate the size of the resulting bitmap
if (upsizeOk || !clipOk)
{
double angleRadians = angleDegrees * Math.PI / 180d;
double cos = Math.Abs(Math.Cos(angleRadians));
double sin = Math.Abs(Math.Sin(angleRadians));
newWidth = (int)Math.Round(oldWidth * cos + oldHeight * sin);
newHeight = (int)Math.Round(oldWidth * sin + oldHeight * cos);
}
// If upsizing not wanted and clipping not OK need a scaling factor
if (!upsizeOk && !clipOk)
{
scaleFactor = Math.Min((float)oldWidth / newWidth, (float)oldHeight / newHeight);
newWidth = oldWidth;
newHeight = oldHeight;
}
// Create the new bitmap object. If background color is transparent it must be 32-bit,
// otherwise 24-bit is good enough.
Bitmap newBitmap = new Bitmap(newWidth, newHeight, backgroundColor == Color.Transparent ?
PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb);
newBitmap.SetResolution(inputImage.HorizontalResolution, inputImage.VerticalResolution);
// Create the Graphics object that does the work
using (Graphics graphicsObject = Graphics.FromImage(newBitmap))
{
// graphicsObject.InterpolationMode = InterpolationMode.HighQualityBicubic;
// graphicsObject.PixelOffsetMode = PixelOffsetMode.HighQuality;
// graphicsObject.SmoothingMode = SmoothingMode.HighQuality;
// Fill in the specified background color if necessary
if (backgroundColor != Color.Transparent)
graphicsObject.Clear(backgroundColor);
// Set up the built-in transformation matrix to do the rotation and maybe scaling
graphicsObject.TranslateTransform(newWidth / 2f, newHeight / 2f);
if (scaleFactor != 1f)
graphicsObject.ScaleTransform(scaleFactor, scaleFactor);
graphicsObject.RotateTransform(angleDegrees);
graphicsObject.TranslateTransform(-oldWidth / 2f, -oldHeight / 2f);
// Draw the result
graphicsObject.DrawImage(inputImage, 0, 0);
}
return newBitmap;
}
And i am Saving the Bitmap with the following method
bmp.Save("C:\\Users\\pamit\\Desktop\\FileName.Tiff", jpgEncoder, myEncoderParameters);
My guess is that you have a very high quality in your encoding parameters.
Try saving it with something like:
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 50L);
myEncoderParameters.Param[0] = myEncoderParameter;
This will save it with a 50% jpeg quality. You can try to tune it to get the desired quality vs size.

C# Image Resizer with Canvas Handler

I'm incredibly new to C# (just started today)
I need to be able to make a C# Image resizer with a canvas handler. For example a 500 x 500 image needs to retain its aspect ration. it will be getting resized to 1024x500. To do this it will remain 500x500 but then fill the rest of the space with white space (the canvas).
I will also be resizing the same original image to 300 x 500, where the image will again retain its 1:1 ration and be resized to 300x300 and the remaining space again used as canvas white space.
Can anybody help me to produce a C# console application for this, that I can understand?
Here is what I have managed to find that I could reasonably understand (due to nice commenting).
What I find with code is that I can read it, but when it comes to me actually writing some I just fall apart. I mainly do HTML and CSS. Starting to branch out into JQuery and C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
namespace ImageResizer
{
class ImageResize
{
static void Main(string[] args)
{
}
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);
}
}
}
Try To Go For This>>
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 + width + "." + originalFilename, info[1],
encoderParameters);
}

Categories