[英]Create a new image on the file system from System.Drawing.Image?
好的,對不起,這可能是一個noob問題,但我有點卡住了。
所以我正在做的(在我的asp.net應用程序上)是從文件系統加載一個圖像:
System.Drawing.Image tempImage;
tempImage = System.Drawing.Image.FromFile(HttpContext.Server.MapPath(originalPath));
然后我做了一些調整大小:
tempImage = my awesomeResizingFunction(tempImage, newSize);
並打算使用以下方法將其保存到另一個位置的文件系統:
string newPath = "/myAwesomePath/newImageName.jpg";
tempImage.Save(newPath);
而我得到的是這個錯誤:
"A generic error occurred in GDI+."
我知道圖像是“正常的”,因為我可以將它寫入瀏覽器並查看已調整大小的圖像,我只是在嘗試保存時才收到錯誤。 我有點新手,我完全錯了嗎? (嗯,我猜這很明顯,但你知道我的意思......)
請嘗試此代碼...我使用了相同的代碼來調整圖像和保存。 如果你有任何問題,請告訴我。
System.Drawing.Bitmap bmpOut = new System.Drawing.Bitmap(NewWidth, NewHeight);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmpOut);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.FillRectangle(System.Drawing.Brushes.White, 0, 0, NewWidth, NewHeight);
g.DrawImage(new System.Drawing.Bitmap(fupProduct.PostedFile.InputStream), 0, 0, NewWidth, NewHeight);
MemoryStream stream = new MemoryStream();
switch (fupProduct.FileName.Substring(fupProduct.FileName.IndexOf('.') + 1).ToLower())
{
case "jpg":
bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
case "jpeg":
bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
case "tiff":
bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Tiff);
break;
case "png":
bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
break;
case "gif":
bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Gif);
break;
}
String saveImagePath = Server.MapPath("../") + "Images/Thumbnail/" + fupProduct.FileName.Substring(fupProduct.FileName.IndexOf('.'));
bmpOut.Save(saveImagePath);
其中fupProduct是fileupload控件ID
您確定originalPath和newPath指向不同的文件嗎? 當您使用Image.FromFile時,文件將保持鎖定狀態,直到您在Image上調用Dispose,這可能會導致您提到的異常。 您可以這樣加載圖像:
Image tempImage = null;
using (FileStream fs = new FileStream(originalPath, FileMode.Open, FileAccess.Read))
{
tempImage = Image.FromStream(fs);
}
...
此方法可確保在使用塊結束時關閉文件
支持原始圖像的原始流是否可能已關閉? 如果Bitmap后面的流已關閉,則會開始出現GDI +錯誤。 當我們在網站上添加圖像處理時,我遇到了很多。
如果在Visual Studio調試器中打開Bitmap對象,是否會看到異常而不是屬性的值? 如果是這樣,它不是保存操作的問題,但是GDI +層已經失去了處理對象的能力。
我發現的是我需要跟蹤屬於我的位圖的MemoryStream並將它們保存在一起。 調整圖像大小會產生帶有新位圖圖像的新MemoryStream。
我最終創建了這個簡單的類(修剪了一些不需要的額外屬性):
public class UploadedImage : IDisposable
{
private Bitmap _img = null;
private Stream _baseStream = null;
/// <summary>
/// The image object. This must always belong to BaseStream, or weird things can happen.
/// </summary>
public Bitmap Img
{
[DebuggerStepThrough]
get { return _img; }
[DebuggerStepThrough]
set { _img = value; }
}
/// <summary>
/// The stream that stores the image. This must ALWAYS belong to Img, or weird things can happen.
/// </summary>
public Stream BaseStream
{
[DebuggerStepThrough]
get { return _baseStream; }
[DebuggerStepThrough]
set { _baseStream = value; }
}
[DebuggerStepThrough]
public void Dispose()
{
if (Img != null)
Img.Dispose();
if (BaseStream != null)
BaseStream.Close();
_attached = false;
}
}
現在,我正在處理上傳到我們網站的圖像,我發現當Asp.Net回收連接到請求的流時,所有突然的圖像操作都開始翻轉。 因此,我的解決方案,無論這是否是最好的方法,是將數據從上傳流復制到我自己的MemoryStream,從中加載圖像,並將兩者都粘貼到此容器中。 無論我從舊的圖像創建新圖像,我總是將流和圖像保持在一起。
我希望這有幫助。
編輯:我也有興趣看到你如何調整圖像大小。 這是我如何做到我們的片段:
temp = new Bitmap(newWidth, newHeight, PIXEL_FORMAT);
temp.SetResolution(newHorizontalRes, newVerticalRes);
gr = Graphics.FromImage(temp);
//
// This copies the active frame from 'img' to the new 'temp' bitmap.
// Also resizes it and makes it super shiny. Sparkle on, mr image dude.
//
Rectangle rect = new Rectangle(0, 0, newWidth, newHeight);
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.SmoothingMode = SmoothingMode.HighSpeed;
gr.PageUnit = GraphicsUnit.Pixel;
gr.DrawImage(img, rect);
//
// Image copied onto the new bitmap. Save the bitmap to a fresh memory stream.
//
retval = new UploadedImage();
retval.BaseStream = (Stream)(new MemoryStream());
temp.Save(retval.BaseStream, ImageFormat.Jpeg);
retval.Img = temp;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.