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
Related
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;
}
I have a routine that scans a folder for images, then for each image, converts it to a thumbnail, and then uploads that thumbnail to a database. It will only run if there isn't any items for that particular folder in the db. My problem is I am receiving an out of memory exception after processing a couple of folders and I'm not sure where the leak is occurring. I have tried disposing of everything disposable that I can in the loop, but obviously something is still falling though the cracks.
private bool LoadImages(int folderid, int parentid) {
ProgressScreen tfrm = new ProgressScreen();
tfrm.Hide();
DataTable mtable = new DataTable();
List<FileInfo> lfile;
mtable = Requests.ProcessSQLCommand(sqlconn, "Select f.ID, f.FolderName,f.FolderPath,f.ParentID,f.Root from Folders f where f.ID = " + folderid);
DataTable ptable = Requests.ProcessSQLCommand(sqlconn, "Select Root from Folders where ID = " + parentid);
if (ptable != null && ptable.Rows.Count > 0) {
if (ptable.Rows[0]["Root"].ToString().ToLower() == "true") {
return false;
}
}
bool process = true;
DirectoryInfo di = new DirectoryInfo(mtable.Rows[0]["FolderPath"].ToString());
FileInfo[] smFiles = di.GetFiles("*.jpg", SearchOption.TopDirectoryOnly);
lfile = smFiles.ToList<FileInfo>();
if (lfile.Count <= 0) {
process = false;
}
if (process) {
tfrm.Show(this);
for (int c = 0; c < lfile.Count; c++) {
if (((FileInfo)lfile[c]).Extension == ".txt") {
lfile.RemoveAt(c);
}
if (((FileInfo)lfile[c]).FullName.ToLower().Contains("cover")) {
lfile.RemoveAt(c);
}
}
for (int b = 0; b < lfile.Count; b++) {
Cursor.Current = Cursors.WaitCursor;
this.Enabled = false;
try {
tfrm.Location = new Point((Screen.PrimaryScreen.WorkingArea.Width / 2) - (tfrm.Width / 2), (Screen.PrimaryScreen.WorkingArea.Height / 2) - (tfrm.Height / 2));
} catch {
}
tfrm.SetProgress((int)(((double)(b + 1) / (double)lfile.Count) * 100), "Loading Images", lfile[b].Name.ToString());
tfrm.Refresh();
int recid = 0;
DataTable ttable = Requests.ProcessSQLCommand(sqlconn, "Insert into Image (Name,FolderID,ParentID) VALUES ('" + lfile[b].Name + "'," + folderid + "," + parentid + ") Select SCOPE_IDENTITY()");
if (ttable != null && ttable.Rows.Count > 0) {
recid = int.Parse(ttable.Rows[0][0].ToString());
}
if (recid > 0) {
Image timg = null;
byte[] traw = new byte[0];
traw = File.ReadAllBytes(lfile[b].FullName);
MemoryStream tstream = new MemoryStream(traw);
timg = System.Drawing.Image.FromStream(tstream);
tstream.Dispose();
timg = Requests.FixedSize(timg, 600, 600);
tstream = new MemoryStream();
timg.Save(tstream, System.Drawing.Imaging.ImageFormat.Png);
timg.Dispose();
traw = new byte[0];
traw = tstream.ToArray();
tstream.Dispose();
System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(sqlconn);
con.Open();
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("Update Image set [Thumb] = Convert(VarBinary(MAX),#Image) where ID = " + recid, con);
cmd.Parameters.AddWithValue("#Image", traw);
cmd.ExecuteNonQuery();
con.Dispose();
}
}
this.Enabled = true;
Cursor.Current = Cursors.Default;
tfrm.Close();
tfrm.Dispose();
System.Windows.Forms.Application.UseWaitCursor = false;
return true;
} else {
return false;
}
}
the Fixed size method:
public 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.Magenta);
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;
}
the original images (before fixed size) range anywhere from 2MB to 20MB, the image returned (max(len(image)) in the table is around 750 KB. (Edit: Corrected files sizes)
Number of images per folder ~100-150
I've looked and debugged, but cannot find what is causing the OOM issues, could someone point me at the error, or offer a better optimization for what I am doing?
If this was a code review, there would be many things I'd suggest as improvements in this code...
But anyway, specifically to your question.. you memory leak is in following lines of code (please don't take it personally, but it was hard to spot, because the code is not as clean)
timg = System.Drawing.Image.FromStream(tstream);
tstream.Dispose();
timg = Requests.FixedSize(timg, 600, 600);
....
timg.Dispose();
You have 2 timg here.. one is original, and the second one is the one you get back from Requests.FixedSize. The timg you passed to Requests.FixedSize does not get disposed.
My requirement is to resize an image if it is bigger than 800 X 600 pixels. I have to resize it to 800 X 600 resolution as per aspect ratio.
I am using below code to re-size it:
public string ResizeUserImage(string fullFileName, int maxHeight, int maxWidth, string newFileName)
{
string savepath = System.Web.HttpContext.Current.Server.MapPath("//InitiativeImage//");
try
{
using (Image originalImage = Image.FromFile(fullFileName))
{
int height = originalImage.Height;
int width = originalImage.Width;
int newHeight = maxHeight;
int newWidth = maxWidth;
if (height > maxHeight || width > maxWidth)
{
if (height > maxHeight)
{
newHeight = maxHeight;
float temp = ((float)width / (float)height) * (float)maxHeight;
newWidth = Convert.ToInt32(temp);
height = newHeight;
width = newWidth;
}
if (width > maxWidth)
{
newWidth = maxWidth;
float temp = ((float)height / (float)width) * (float)maxWidth;
newHeight = Convert.ToInt32(temp);
}
Image.GetThumbnailImageAbort abort = new Image.GetThumbnailImageAbort(ThumbnailCallback);
using (Image resizedImage = originalImage.GetThumbnailImage(newWidth, newHeight, abort, System.IntPtr.Zero))
{
//When image is compress then store the image
var guid = Guid.NewGuid().ToString();
string latestFileName = guid + Path.GetExtension(newFileName);
resizedImage.Save(savepath + #"\" + latestFileName);
string finalPath = AppSettings.Domain + "InitiativeImage/" + latestFileName;
return finalPath;
}
}
else if (fullFileName != newFileName)
{
//var guid = Guid.NewGuid().ToString();
//newFileName = guid + Path.GetExtension(newFileName);
//// no resizing necessary, but need to create new file
//originalImage.Save(savepath + #"\" + newFileName);
//string finalPath = AppSettings.Domain + "UserImage/" + newFileName;
return newFileName;
}
return fullFileName;
}
}
catch (Exception)
{
throw;
}
}
It works perfect but resizing image gets damaged in pixel.
See below original image which I am uploading to the server:
After re-sizing it, it is damages like below image:
Hope you got my question. The resized image get damage in pixel. Please let me know where I am wrong or where is the issue.
Pls try out below function.
public void FixedSize(string oldImageFile, int Width, int Height,string finalpath)
{
Bitmap imgPhoto = new Bitmap(oldImageFile);
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(destWidth, destHeight,
PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.Clear(Color.White);
grPhoto.InterpolationMode =
InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(0, 0, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
bmPhoto.Save(finalpath);
}
From the documentation on Image.GetThumbnailImage method:
The GetThumbnailImage method works well when the requested thumbnail image has a size of about 120 x 120 pixels. If you request a large thumbnail image (for example, 300 x 300) from an Image that has an embedded thumbnail, there could be a noticeable loss of quality in the thumbnail image. It might be better to scale the main image (instead of scaling the embedded thumbnail) by calling the DrawImage method.
But your objective size is around 800x600 pixels, which is way above the indented use.
Thus, I recommend you to take a look at this answer about image resizing.
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;
}
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);
}
}
}