سلام.
آیا به این مساله دقت کرده اید که کلاس Image، در واقع یک abstract class هستش؟ پس Image.FromStream چطوری میتونه یک Image برگردونه، در حالیکه Image فقط یک abstract class ای هستش که نمیشه Instantiate اش کرد؟ خوب، واضحه. فقط در یک صورت چنین امکانی وجود داره و اونم این هستش که متود مزبور حتما داره Instance ای از کلاسی میسازه که از Image درایو شده که فقط در این صورت هستش که میتونه مقدار بازگشی رو به Image کست کنه و اونو از طریق FromStream برگردونه. حالا سوال تغییر میکنه: "این چه کلاسی هستش که FromStream درون خودش Instantiate میکنه و با استفاده از اون Image رو به ما برمیگردونه؟"

این کلاس، کلاس Bitmap هستش. کلاسی که از Image درایو شده، و در درون Image.FromStream در حقیقت داره Instantiate میشه. در حقیقت در کلاس Image، متودی با Signature زیر وجود داره که این کارو در درون خودش انجام میده:

internal static Image CreateImageObject(IntPtr nativeImage);


در درون این متود، جایی Bitmap.FromGDIplus فراخوانی میشه، متودی که Instance ای از کلاس Bitmap (بر اساس native image ای که بعنوان formal parameter بهش داده شده) میسازه. اما دونستن این مطالب چه کمکی به دلیل پی بردن به اون خطا میکنه؟ پاسخ اینجاست که اگر به مستندات کلاس Bitmap توجه کنید، اولین خط در بخش Remark نوشته شده که "شما باید stream را در طول حیات Bitmap، باز نگه دارید". درسته شده دارید یک Image Instance از متود Image.FromStream میگیرید، اما اون Instance توسط Bitmap.FromGDIplus ایجاد میشه و Bitmap کلاسی هستش که داره Instantiate میشه. در حقیقت اینجا شما دارید "مالکیت" اون stream ر به Bitmap واگذار می کنید، پس اجازه ندارید تا مادامیکه کلاس Bitmap در حافظه هستش اون Stream رو از بین ببریبد. حالا با این توضیحات، میتونیم به این سوال شما پاسخ بدیم:

خب فک کنید من تعداد زیادی عکسو اینطوری تبدیل کنم نمیخواد منابع مربوط به memoryStream اونها ازاد بشن؟
کافیه تا Image دریافت شده رو Dispose کنید. بدین ترتیب Image به نوبه خودش Stream مربوطه رو آزاد خواهد کرد. (چون باز هم تکرار میکنم، مالکیت Stream در حال حاضر در اختیار Image قرار گرفته).

موفق باشید.