Unable to save .bmp image to server from ASP.NET - c#

In an ASP.net (C#) web app I have created a signature pad using HTML 5 canvas and java script. We are capturing the signature with touch devices (android and iOS).
When the signature is completed it sends the data from the canvas to the server where I convert it to a .bmp image and save it to a directory called signature files on the root program directory on the server using Bitmap.Save(location, Format). This has been working fine for several clients for many months until now.
Unfortunately I am currently catching exceptions but not sending them anywhere (huge mistake that I am currently working on rectifying). If I have to I will recompile the code with some exception outputs so that I can get more information but since its a new client I would love to be able to fix this asap and since the code has been working for a long time without issue, I'm optimistic that its a server setting.
Is there a security setting in IIS7 or Windows Server 2008 that may be blocking the app from saving a file to the server. If not is there something that may need to be installed on the server to allow the following:
byte[] imageBytes = Convert.FromBase64String(suffix);
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
ms.Write(imageBytes, 0, imageBytes.Length);
string thePath = Path.GetDirectoryName(saveLocation);
FileStream fs = new FileStream(thePath + #"\image.png", FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(imageBytes);
bw.Close();
if (string.IsNullOrEmpty(Path.GetFileName(saveLocation)))
{
string filename = Path.GetRandomFileName();
filename = filename.Substring(0, filename.IndexOf('.'));
filename = filename + Path.GetRandomFileName();
filename = filename.Substring(0, filename.IndexOf('.'));
theSaveLocation = saveLocation + #"\" + filename + "." + format;
}
ms = new MemoryStream();
Bitmap input = (Bitmap)Bitmap.FromFile(thePath + #"\image.png");
Bitmap result = ProcessBitmap(input, Color.White);
result = (Bitmap)resizeImage((System.Drawing.Image)result, size);
result.Save(theSaveLocation, System.Drawing.Imaging.ImageFormat.Bmp);
input.Dispose();
result.Dispose();
ms.Close();
Here's the process Bitmap function that I used above
private Bitmap ProcessBitmap(Bitmap bitmap, Color color)
{
Bitmap temp = new Bitmap(bitmap.Width, bitmap.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(temp);
g.Clear(color);
g.DrawImage(bitmap, Point.Empty);
return temp;
}
Here's the resizeImage function that I used above:
private static System.Drawing.Image resizeImage(System.Drawing.Image imgToResize, Size size)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)size.Width / (float)sourceWidth);
nPercentH = ((float)size.Height / (float)sourceHeight);
if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap b = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage((System.Drawing.Image)b);
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
g.Dispose();
return (System.Drawing.Image)b;
}

Related

C# Can't convert byte to image

The code works on the tutorial I've watched but not on mine.
Here's my code:
private void AddButton()
{
foreach (TblProductType category in cse.TblProductType)
{
Button btn = new Button();
btn.Text = category.Description;
btn.Size = new Size(100, 100);
btn.ForeColor = Color.White;
byte [] dataCategory1 = category.Productimage;
MemoryStream stm = new MemoryStream(dataCategory1);
btn.Image = Image.FromStream(stm);
btn.Image = ResizeImage(btn.Image, btn.Size);
btn.Tag = category.ProductTypes;
flow1.Controls.Add(btn);
this.Controls.Add(flow1);
btn.Click += btn_Click
}
}
We may need a little more surrounding code, or a more information to the exact nature of your problem, but i suspect the most likely cause of this issue is whatever is happening in ResizeImage.
Here's a function which resizes a System.Drawing.Image, perhaps give that a try and see if it fixes your problem?
public static Image ResizeImage(int newWidth, int newHeight, Image image) {
int sourceWidth = image.Width;
int sourceHeight = image.Height;
//Consider vertical pics
if (sourceWidth < sourceHeight) {
int buff = newWidth;
newWidth = newHeight;
newHeight = buff;
}
int sourceX = 0, sourceY = 0, destX = 0, destY = 0;
float percent = 0, percentW = 0, percentH = 0;
percentW = ((float)newWidth / (float)sourceWidth);
percentH = ((float)newHeight / (float)sourceHeight);
if (percentH < percentW) {
percent = percentH;
destX = System.Convert.ToInt16((newWidth -
(sourceWidth * percent)) / 2);
} else {
percent = percentW;
destY = System.Convert.ToInt16((newHeight -
(sourceHeight * percent)) / 2);
}
int destWidth = (int)(sourceWidth * percent);
int destHeight = (int)(sourceHeight * percent);
Bitmap bitmap = new Bitmap(newWidth, newHeight,
PixelFormat.Format24bppRgb);
bitmap.SetResolution(image.HorizontalResolution,
image.VerticalResolution);
Graphics graphic = Graphics.FromImage(bitmap);
graphic.Clear(Color.Black);
graphic.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphic.DrawImage(image,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
graphic.Dispose();
image.Dispose();
return bitmap;
}
Here, try this:
In my problem I saved my chart to an memoryStream.. then saved that memoryStream to byte array and then saved byte array to an image. It works for me.
using (MemoryStream memoryStream = new MemoryStream())
{
//saved my chart to an memoryStream
Chart2.SaveImage(memoryStream, ChartImageFormat.Png);
//saved memorystream to byte array
byte[] byteArrayIn = memoryStream.ToArray();
//saving byte back to an Image
Image image1 = new Image();
image1.ImageUrl = "data:image/png;base64," + Convert.ToBase64String(byteArrayIn, 0, byteArrayIn.Length);
newChart.Controls.Add(image1);
divRadarChart.Visible = false;
}

End of Stream Parsing Error

public static Image Crop(Image imgPhoto, int Width, int Height, AnchorPosition Anchor)
{
if (imgPhoto == null)
{
return null;
}
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 = nPercentW;
switch (Anchor)
{
case AnchorPosition.Top:
destY = 0;
break;
case AnchorPosition.Bottom:
destY = (int)(Height - (sourceHeight * nPercent));
break;
default:
destY = (int)((Height - (sourceHeight * nPercent)) / 2);
break;
}
}
else
{
nPercent = nPercentH;
switch (Anchor)
{
case AnchorPosition.Left:
destX = 0;
break;
case AnchorPosition.Right:
destX = (int)(Width - (sourceWidth * nPercent));
break;
default:
destX = (int)((Width - (sourceWidth * nPercent)) / 2);
break;
}
}
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.InterpolationMode = InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
public byte[] ImageToByteArray(string path)
{
FileInfo info = new FileInfo(path);
long sizeByte = info.Length;
FileStream fs = new FileStream(path,FileMode.Open,FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
byte[] data = br.ReadBytes((int) sizeByte);
return data;
}
public byte[] ImageToByteArray(Image img)
{
if (img == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, img);
return ms.ToArray();
}
public Image BrowseImage(Image image)
{
OpenFileDialog open = new OpenFileDialog();
open.FileName = string.Empty;
open.Filter = "Image Files(*.png; *.jpg; *.jpeg; *.gif; *.bmp)|*.png; *.jpg; *.jpeg; *.gif; *.bmp";
if (open.ShowDialog() == DialogResult.OK)
{
Image img = new Bitmap(open.FileName);
if ((img.Width < 200) || (img.Height < 200))
{
MessageBox.Show("Minimum size is 200x200.");
BrowseImage(image);
}
else
{
return img;
}
}
return image;
}
in saving image
picItem.Image = Crop(BrowseImage(picItem.Image), 200, 200, ImageUtil.AnchorPosition.Center);
//set Datatable row
erow["Image"] = img.ImageToByteArray(picItem.Image);
//Saving is ok
//When i View
picItem.Image = ByteArrayToImage((byte[])source.Image.binaryFromDB);
>Error: End of Stream encountered before parsing was completed?
this is all the method ive use. i crop the image so that it will have a minimum size..ive tried any convertion but no help.
i just want to save an image to database and when i view i can see the image in picture box.
#MarcGravell I found the problem. u right man.when i store the byte in datatable it stores a value System.Byte[] not the actual bytes.. when i get all the value in datatable and put it in a query "Insert into table values('System.Byte[]'). .it stores a string System.Byte" not the binary data..
You've loaded all the data into the MemoryStream and rewound the stream - all good (although new MemoryStream(byteArrayIn) would have been easier).
This leaves one simple possibility: the array truly does not contain all of the data that it should have.
Check how you got the array, and all intermediary steps. In particular, add some debug code to note the length of the array when you write it, and check that you got all of it. If the length is the same, check that the contents are identical byte-for-byte (comparing the output of Convert.ToBase64String is probably the most convenient way of doing that for ad-hoc usage).
If you are writing streams, check a few things:
if using a Stream.Read/Stream.Write loop, check you are using the return value from Read correctly; or easier - just use Stream.CopyTo instead (this has a correctly-implemented Read/Write loop)
if using MemoryStream, make sure you understand the difference between ToArray and GetBuffer, and the implications of each
if you are transferring the data at any point, make sure you are treating it as binary at all times - never text. No StreamReader / StreamWriter / Encoding / GetString / anything like that

Image resize asp.net mvc application

POST EDITED ADDED THE LINK
Read a very good post on image resize [here][1] in asp.net mvc.
http://dotnetslackers.com/articles/aspnet/Testing-Inbound-Routes.aspx
I need this logic to work for the images that are uploaded in cdn also.Say for example i have uploaded an image in cdn and now i want to fetch it from my controller and resize it.Also the image should not be saved in my server as it will not be good idea as it consumes valuable resource.The image has to be read from CDN and re sized without saving it locally in server.How can we achieve this using the methodology given in the above post.
Thanks,
S.
If you use ASP.Net MVC3, you can try new helper - WebImage.
This is my test code.
public ActionResult GetImg(float rate)
{
WebClient client = new WebClient();
byte[] imgContent = client.DownloadData("ImgUrl");
WebImage img = new WebImage(imgContent);
img.Resize((int)(img.Width * rate), (int)(img.Height * rate));
img.Write();
return null;
}
You can use the GDI+ features in the System.Drawing namespace
Bitmap newBitmap = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage((Image)newBitmap);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(sourceImage, 0, 0, destWidth, destHeight);
g.Dispose();
Here's what I use. Works great.
private static Image ResizeImage(Image imgToResize, Size size)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)size.Width / (float)sourceWidth);
nPercentH = ((float)size.Height / (float)sourceHeight);
if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap b = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
g.Dispose();
return (Image)b;
}

convert bitonal TIFF to bitonal PNG in C#

I need to convert bitonal (black and white) TIFF files into another format for display by a web browser, currently we're using JPGs, but the format isn't crucial. From reading around .NET doesn't seem to easily support writing bitonal images, so we're ending up with ~1MB files instead of ~100K ones. I'm considering using ImageMagick to do this, but ideally i'd like a solution which doesn't require this if possible.
Current code snippet (which also does some resizing on the image):
using (Image img = Image.FromFile(imageName))
{
using (Bitmap resized = new Bitmap(resizedWidth, resizedHeight)
{
using (Graphics g = Graphics.FromImage(resized))
{
g.DrawImage(img, new Rectangle(0, 0, resized.Width, resized.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
}
resized.Save(outputFilename, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
Is there any way to achieve this?
Thanks.
I believe the problem can be solved by checking that resized bitmap is of PixelFormat.Format1bppIndexed. If it's not, you should convert it to 1bpp bitmap and after that you can save it as black and white png without problems.
In other words, you should use following code instead of resized.Save(outputFilename, System.Drawing.Imaging.ImageFormat.Jpeg);
if (resized.PixelFormat != PixelFormat.Format1bppIndexed)
{
using (Bitmap bmp = convertToBitonal(resized))
bmp.Save(outputFilename, System.Drawing.Imaging.ImageFormat.Png);
}
else
{
resized.Save(outputFilename, System.Drawing.Imaging.ImageFormat.Png);
}
I use following code for convertToBitonal :
private static Bitmap convertToBitonal(Bitmap original)
{
int sourceStride;
byte[] sourceBuffer = extractBytes(original, out sourceStride);
// Create destination bitmap
Bitmap destination = new Bitmap(original.Width, original.Height,
PixelFormat.Format1bppIndexed);
destination.SetResolution(original.HorizontalResolution, original.VerticalResolution);
// Lock destination bitmap in memory
BitmapData destinationData = destination.LockBits(
new Rectangle(0, 0, destination.Width, destination.Height),
ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);
// Create buffer for destination bitmap bits
int imageSize = destinationData.Stride * destinationData.Height;
byte[] destinationBuffer = new byte[imageSize];
int sourceIndex = 0;
int destinationIndex = 0;
int pixelTotal = 0;
byte destinationValue = 0;
int pixelValue = 128;
int height = destination.Height;
int width = destination.Width;
int threshold = 500;
for (int y = 0; y < height; y++)
{
sourceIndex = y * sourceStride;
destinationIndex = y * destinationData.Stride;
destinationValue = 0;
pixelValue = 128;
for (int x = 0; x < width; x++)
{
// Compute pixel brightness (i.e. total of Red, Green, and Blue values)
pixelTotal = sourceBuffer[sourceIndex + 1] + sourceBuffer[sourceIndex + 2] +
sourceBuffer[sourceIndex + 3];
if (pixelTotal > threshold)
destinationValue += (byte)pixelValue;
if (pixelValue == 1)
{
destinationBuffer[destinationIndex] = destinationValue;
destinationIndex++;
destinationValue = 0;
pixelValue = 128;
}
else
{
pixelValue >>= 1;
}
sourceIndex += 4;
}
if (pixelValue != 128)
destinationBuffer[destinationIndex] = destinationValue;
}
Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);
destination.UnlockBits(destinationData);
return destination;
}
private static byte[] extractBytes(Bitmap original, out int stride)
{
Bitmap source = null;
try
{
// If original bitmap is not already in 32 BPP, ARGB format, then convert
if (original.PixelFormat != PixelFormat.Format32bppArgb)
{
source = new Bitmap(original.Width, original.Height, PixelFormat.Format32bppArgb);
source.SetResolution(original.HorizontalResolution, original.VerticalResolution);
using (Graphics g = Graphics.FromImage(source))
{
g.DrawImageUnscaled(original, 0, 0);
}
}
else
{
source = original;
}
// Lock source bitmap in memory
BitmapData sourceData = source.LockBits(
new Rectangle(0, 0, source.Width, source.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
// Copy image data to binary array
int imageSize = sourceData.Stride * sourceData.Height;
byte[] sourceBuffer = new byte[imageSize];
Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);
// Unlock source bitmap
source.UnlockBits(sourceData);
stride = sourceData.Stride;
return sourceBuffer;
}
finally
{
if (source != original)
source.Dispose();
}
}
Have you tried saving using the Image.Save overload with Encoder parameters?
Like the Encoder.ColorDepth Parameter?
Trying jaroslav's suggestion for color depth doesn't work:
static void Main(string[] args)
{
var list = ImageCodecInfo.GetImageDecoders();
var jpegEncoder = list[1]; // i know this is the jpeg encoder by inspection
Bitmap bitmap = new Bitmap(500, 500);
Graphics g = Graphics.FromImage(bitmap);
g.DrawRectangle(new Pen(Color.Red), 10, 10, 300, 300);
var encoderParams = new EncoderParameters();
encoderParams.Param[0] = new EncoderParameter(Encoder.ColorDepth, 2);
bitmap.Save(#"c:\newbitmap.jpeg", jpegEncoder, encoderParams);
}
The jpeg is still a full color jpeg.
I don't think there is any support for grayscale jpeg in gdi plus. Have you tried looking in windows imaging component?
http://www.microsoft.com/downloads/details.aspx?FamilyID=8e011506-6307-445b-b950-215def45ddd8&displaylang=en
code example: http://www.codeproject.com/KB/GDI-plus/windows_imaging.aspx
wikipedia: http://en.wikipedia.org/wiki/Windows_Imaging_Component
This is an old thread. However, I'll add my 2 cents.
I use AForge.Net libraries (open source)
use these dlls. Aforge.dll, AForge.Imaging.dll
using AForge.Imaging.Filters;
private void ConvertBitmap()
{
markedBitmap = Grayscale.CommonAlgorithms.RMY.Apply(markedBitmap);
ApplyFilter(new FloydSteinbergDithering());
}
private void ApplyFilter(IFilter filter)
{
// apply filter
convertedBitmap = filter.Apply(markedBitmap);
}
Have you tried PNG with 1 bit color depth?
To achieve a size similar to a CCITT4 TIFF, I believe your image needs to use a 1-bit indexed pallette.
However, you can't use the Graphics object in .NET to draw on an indexed image.
You will probably have to use LockBits to manipulate each pixel.
See Bob Powell's excellent article.

Resize image gdi+ graphics .net

I have this method for shrinking down an image for a website that I'm working on:
static byte[] createSmallerImage(
BlogPhoto blogPhoto,
int newMaxWidth,
int newMaxHeight)
{
Image img;
using (MemoryStream originalImage =
new MemoryStream(blogPhoto.BlogPhotoImage))
{
img = Image.FromStream(originalImage);
}
int newWidth;
int newHeight;
byte[] arr;
if (img.Width > img.Height)
{
if (img.Width <= newMaxWidth)
{
using (MemoryStream thumbStr = new MemoryStream())
{
img.Save(thumbStr, ImageFormat.Jpeg);
img.Dispose();
arr = thumbStr.ToArray();
}
return arr;
}
newWidth = newMaxWidth;
newHeight =
(int)(((float)newWidth / (float)img.Width) * (float)img.Height);
}
else
{
if (img.Height <= newMaxHeight)
{
using (MemoryStream thumbStr = new MemoryStream())
{
img.Save(thumbStr, ImageFormat.Jpeg);
img.Dispose();
arr = thumbStr.ToArray();
}
return arr;
}
newHeight = newMaxHeight;
newWidth =
(int)(((float)newHeight / (float)img.Height) * (float)img.Width);
}
Image thumb = new Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage(thumb);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(img, 0f, 0f, (float)newWidth, (float)newHeight);
using (MemoryStream thumbStr = new MemoryStream())
{
thumb.Save(thumbStr, ImageFormat.Jpeg);
arr = thumbStr.ToArray();
}
g.Dispose();
img.Dispose();
return arr;
}
Most of the time it works great but sometimes it gives me this exception:A generic error occurred in GDI+. Error Code -2147467259. Source: "System.Drawing". This occurs on the Image.Save(... I tried to make this code as defensive as possible but am still not getting whats causing this. If someone knows the answer that'd be great, critiques are welcome too.
I personally use this code, with no streams (I don't care about perfs, though) for resizing a picture:
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 =
InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
Hope this helps.
Look at the documentation for Image.FromStream()
http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx
You need to keep the stream open for the lifetime of the Image. Keep the first MemoryStream open longer, and it should work.
One thing to look at is blogPhoto and the underlying data going away. Where does it get loaded from? Is it loaded from a stream? Is that stream closed before createSmallerImage? Images loaded from streams where the stream is closed work 95% of the time and only occaisonally throw a generic GDI+ error.
I don't know what can be happening, but maybe with less MemoryStreams problem go away:
using (Image original = Image.FromStream(new MemoryStream(blogPhoto)))
{
using (MemoryStream thumbData = new MemoryStream())
{
int newWidth;
int newHeight;
if ((original.Width <= newMaxWidth) ||
(original.Height <= newMaxHeight))
{
original.Save(thumbData, ImageFormat.Jpeg);
return thumbData.ToArray();
}
if (original.Width > original.Height)
{
newWidth = newMaxWidth;
newHeight = (int)(((float)newWidth /
(float)original.Width) * (float)original.Height);
}
else
{
newHeight = newMaxHeight;
newWidth = (int)(((float)newHeight /
(float)original.Height) * (float)original.Width);
}
//original.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero)
// .Save(thumbData, ImageFormat.Jpeg);
//return thumbData.ToArray();
using (Image thumb = new Bitmap(newWidth, newHeight))
{
Graphics g = Graphics.FromImage(thumb);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(original, 0f, 0f, (float)newWidth, (float)newHeight);
thumb.Save(thumbData, ImageFormat.Jpeg);
}
}
}

Categories