PDA

View Full Version : سوال: مشکل در ذخیره عکس روی سرور(error in GDI)



amrssh2008
جمعه 12 مهر 1387, 18:05 عصر
با سلام خدمت دوستان گرامی

بنده در طراحی و ایجاد یه برنامه تحت وب به مشکلی برخورد کردم !

این برنامه قراره آدرس یک عکس رو بگیره و اون رو در ابعاد مشخص ببره و عکس نهایی رو روی سرور ذخیره کنه و ...

من این رو نوشتم و کاملا درست روی لوکال اجرا میشه و در لوکال هیچ مشکلی نداره ، حتی روی یه هاست مجانی هم تست کرده بودم و کامل جواب گرفتم .

اما مشکل اینجاست که الان روی یه هاست آپلود کردم ، و هنگام ذخیره کردن عکس نهایی ، به ارور در GDI برخوردم ، توی گوگل ، این سایت و خیلی سایتهای دیگه سرچ کردم و متوجه شدم عده زیادی مشکل من رو دارند و راه حلهایی بود از قبیل آزاد کردن فضای اختصاص یافته به Bitmap های استفاده شده از طریق Dispose کردن اونها و ... اما باز هم جواب نگرفتم !!

من کد تابعی که برای اینکار نوشتم رو اینجا قرار میدم و خطی که اررور داره رو Bold میکنم :




Private Function Crop(ByVal mapadr As String, ByVal x As Int32, ByVal y As Int32, ByVal width As Int32, ByVal height As Int32) As System.Drawing.Bitmap

Dim img As System.Drawing.Bitmap = System.Drawing.Image.FromFile(Server.MapPath(mapad r))

Dim Cropped As New System.Drawing.Bitmap(width, height)
Dim g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(Cropped)
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQu ality
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQua lityBicubic
Dim rect As New System.Drawing.Rectangle(0, 0, width, height)
g.DrawImage(img, rect, x, y, width, height, System.Drawing.GraphicsUnit.Pixel)


img.Dispose()
g.Dispose()

Cropped.Save(Server.MapPath("/images/sum.jpg"))
Return Cropped

End Function


و این هم متن ارور :



ExternalException (0x80004005): A generic error occurred in GDI+.]
System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams) +377518
System.Drawing.Image.Save(String filename, ImageFormat format) +69
System.Drawing.Image.Save(String filename) +25
_Default.Page_Load(Object sender, EventArgs e) in
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +50
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627

بسیار بسیار ممنون میشم اگه از دوستان و اساتید کسی راه حل این مشکل رو بفرمایند چون موضوع خیلی برام مهم هست

Behrouz_Rad
جمعه 12 مهر 1387, 20:40 عصر
عرض شود که در زمان دات نت 1.1 که بنده به این مشکل برخورد کردم، یک روز وقتم گرفته شده تا دلیل بروز مشکل رو فهمیدم. دلیل رو میگم... باشد که راه برای آیندگان هموار شود ;)

+GDI برای افزایش کارایی، فقط Header تصویر رو می خونه تا از طریق اون اطلاعات مورد نیاز برای کار با تصویر مثل طول، عرض، تعداد رنگ ها و ... رو به دست بیاره.
پس از دریافت این اطلاعات، فایل رو نمیبنده و همچنان باز نگه میداره!
در نتیجه وقتی که قرار هست با شی اصلی که تصویر رو باز کرده کار کنی و روی اون تغییری بدی، چون نمیشه بر روی فایلی که باز هست تغییر داد، با اون خطا مواجه میشی.
خط مشکل ساز در کدهایی که نوشتی این هست:


g.DrawImage(img, rect, x, y, width, height, System.Drawing.GraphicsUnit.Pixel)

قبل از اینکه img رو Dispose کنی، سعی در انجام عملیات بر روی اون رو داری!

روش صحیح این هست که پس از باز کردن فایل، یک تصویر موقت در حافظه با Image درست کنی. با شی Graphics به این تصویر موقت ارجاع پیدا کنی. تصویر اصلی رو به تصویر موقت انتقال بدی و بعد از اون بلافاصله شی تصویر اصلی رو Dispose کنی. از این به بعد هر عملیات ویرایش رو با استفاده از شی Grpahics بر روی تصویر موقت انجام بده و بعد از اون Graphics رو Dispose و تصویر موقت رو بر روی دیسک ذخیره کن.
کدی مثل ذیل:


Image i = Image.FromFile(s);
Image t=new Bitmap(i.Width,i.Height);
Graphics g=Graphics.FromImage(t);
g.DrawImage(i,0,0);
i.Dispose();
//do something with g


موفق باشید.

amrssh2008
جمعه 12 مهر 1387, 22:31 عصر
بسیار ممنون از راهنماییهاتون جناب آقای راد ، این نکته ای که فرمودین حتما به کارم میاد

اما مشکل من خیییلی ساده تر از اینها بود!! پرمیشن ها درست نبودن !!! خدا رو شکر الان مشکل حل شد

باز هم ممنون از توجهتون