PDA

View Full Version : ذخیره و چاپ عکس و حجیم شدن مسیر Windows\winsxs



mh3242
چهارشنبه 19 شهریور 1393, 11:11 صبح
سلام خدمت دوستان
من یه برنامه نوشتم که یه سری عکس که توی picturebox ها هستن رو اول ذخیره میکنه رو هارد دیسک تو مسیر خود برنامه و بعدشم چاپشون میکنه. خود برنامه بدون هیچ مشکلی داره کار میکنه. ولی بعد از یه مدت متوجه شدم درایو ویندوز خیلی پر شده به حدی که چند ده MB جای خالی داره.
اینم بگم که از ویندوز 7 استفاده میشه.
شک کردم که لنگ کار از برنامم باشه. گشتم تو درایو ویندوز و دیدم که پوشه winsxs بیشتر از 6GB حجم داره. و اصلا هم نمیشه چیزی ازش حذف کرد. تو نت هم سرچ زدم. راه حل هایی که وجود داشت استفاده از disk cleanup بود که فضای خیلی کمی رو آزاد میکرد.
اما یه جایی خوندم که هر فایلی توی کل کامپیوتر ایجاد میشه یه لینکی به این پوشه داره. برگشتم و برنامه رو اجرا کردم و چندین بار عکسها رو پرینت گرفتم (همزمان با پرینت گرفتن برنامه به صورت خودکار عکس ها رو ذخیره میکنه). چیزی که دیدم این بود که بعد از هر بار چاپ کردن بیشتر از 100MB تغییر حجم تو درایو ویندوز میدیدم!!! این در حالی هستش که کل حجمی که من با برنامم ذخیره میکردم کمتر از 5MB بود.
خب حالا کد های برنامه:
قسمت ذخیره عکس:



try
{
Directory.CreateDirectory(Environment.CurrentDirec tory + ... );
for (int c = 0; c < 13; C++‎‎‎‎‎‎‎‎‎‎)
{
if (File.Exists(Environment.CurrentDirectory + ... + (c + 1).ToString() + ".JPEG"))
File.Delete(Environment.CurrentDirectory + ... + (c + 1).ToString() + ".JPEG");
ImageArrayForSave[c].Save(Environment.CurrentDirectory + ... + (c + 1).ToString() + ".JPEG", ImageFormat.Jpeg);
}
PrintDocument.PrinterSettings = PrintDialog.PrinterSettings;
PrintDocument.Print();
this.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
PrintDocument.Dispose();
}



و قسمت چاپ:



private void PrintDocument_PrintPage(object sender, PrintPageEventArgs e)
{
Rectangle Rec;
Rec = new Rectangle(0, 0, (int)Support.ToPixelsX(210, ScaleMode.Millimeters), (int)Support.ToPixelsX(297, ScaleMode.Millimeters));
e.Graphics.DrawImage(ImageArrayForPrint[Counter], Rec);
Counter++;
if (Counter < NumberOfPages)
{
e.HasMorePages = true;
}
}



حالا از اساتید محترم درخواست دارم اگه میتونن راه حلی برای جلوگیری از این افزایش حجم ارائه بدن.

با تشکر

ro3vayedel
چهارشنبه 19 شهریور 1393, 17:34 عصر
بجای ذخیره آدرس عکس و کپی گرفتن از روی عکس توی دیتابیس فیلدی بنام pic با نوع داده image معرفی کن ... اونوقت عکس به بایت تبدیل میشه و چندبایت بیشتر ذخیره نمیشه...
خیلی خیلی حجم برنامه رو پایین میاره و دیگه جایی رو پر نمیکنه...

ro3vayedel
چهارشنبه 19 شهریور 1393, 17:36 عصر
عکس انتخاب شده توسط کاربر به صورت آرایه ای از بایت ها در دیتابیس ذخیره می گردد و امکان بازخوانی همان عکس نیز فراهم می شود.با شروع برنامه اتصالی به بانک Image که همراه برنامه موجود می باشد برقرار می گردد.با کلیک برروی دکمه Add Picture ابتدا با کمک آدرس فایل انتخاب شده توسط کاربردر متغیر شیء جدیدی از کلاس Bitmapساخته می شود و در متغیر img ذخیره می گردد. سپس این Bitmap ایجاد شده در حافظه جریان حافظه ای به نام mstrقرار می گیرد.حال برای تبدیل این جریان حافظه به آرایه ای از بایت از تابع Getbuffer استفاده می کنیم. این تابع در حقیقت آرایه ای از بایت هایی که توسط متغیر mstr ساخته شده اند را بازمیگرداند. ما این مقدار را در آرایه ای به نام arrImageذخیره کرده ایم. حال با استفاده از شیء SqlDataAdapter و استفاده از sqlconnectionای که در ابتدای شروع برنامه آن را وصل کرده بودیم تمامی اطلاعات از جدول info را داخل این شیء قرار می دهیم. حال شیء ای از کلاس Dataset می سازیم و آن را با استفاده از SqlDataAdapter پر می کنیم:SqlDataAdapter da = new SqlDataAdapter("select * from Info", conn);DataSet ds = new DataSet();da.Fill(ds);حال همانطور که در قطعه کد زیر نشان داده شده است رکورد جدیدی ایجاد می کنیم و فیلد اول این رکورد را با آرایهarrImage که نگهدارنده اطلاعات مربوط به عکس انتخاب شده است پر می کنیمو این رکورد جدید را به دیتاست اضافه می کنیم.DataRow dr = ds.Tables[0].NewRow();dr[1] = arrImage;ds.Tables[0].Rows.Add(dr);SqlCommandBuilder sc = new SqlCommandBuilder(da);da.Update(ds.Tables[0]);سپس برای اینکه تغییر در بانک اعمال شود یک شیء از کلاس SqlCommandBuilder ساخته می شود و دیتاآداپتر مورد استفاده به عنوان پارامتر به آن پاس داده می شود و با استفاده از دستور Update تغییرات انجام شده در دیتاست در بانک ذخیره می شود.برای بازخوانی عکس عملیات اضافه کردن انجام می گیرد. بدین صورت که ابتدا اطلاعات از فیلد مورد نظر بازخوانی شده و در آرایه ای از بایت به نام b ذخیره می شود. حال این آرایه در مموری استریمی به نام mem در حافظه بارگذاری می شود و در انتها عکس از روی این فایل استریم ساخته می شود و درون شیءPicture قرار می دهیم.

mh3242
چهارشنبه 19 شهریور 1393, 18:10 عصر
خیلی ممنون دوست عزیز بابت زحمتی که کشیدین و وقتی که گذاشتین.
من فکر میکنم 3 حالت بیشتر وجود نداره. یا من بد توضیح دادم یا شما کامل متوجه نشدین یا اصلا سوال رو نخوندین.
من نگفتم میخوام آدرس عکس رو تو دیتابیس ذخیره کنم و ضمنا حتما اینو هم میدونید که ذخیره عکس تو دیتابیس حجم خود دیتا بیس رو خیلی زیاد میکنه و بصورت اختصاصی (تو برنامه خودم) طبق توضیحاتی که ندادم و با توجه به موضوع تاپیک نیازی هم بهشون نبوده!!! اصلا نباید عکس ها رو تو دیتابیس ذخیره کنم.
دلیل: عکس اصلی رو دارم. اطلاعاتی هم که باید به عکس اضافه بشه رو بصورت تکست دارم. اونوقت بیام و ازشون عکس تولید کنم و بعدشم عکس رو تو دیتابیس ذخیره کنم؟؟؟ فکر میکنم زیاد جالب نباشه. دلیل ذخیره عکس هم این بود که مشتری نیاز داره.
دقت کنید حجم برنامه بالا نمیره. با این که من تو برنامه بیشتر از 17000 تا عکس دارم ،حجم عکس ها از 600MB بیشتر نشده ولی همونطور که گفتم پوشه winsxs بیشتر از 6GB حجم پیدا کرده و همینطور هم داره بیشتر میشه!!!
من اینجا مشکل دارم. یعنی میخوام بدونم مثلا روش ذخیره عکسی که من دارم ازش استفاده میکنم اشتباه هستش یا درسته ولی چیزی کم داره یا از این قبیل مسائل.
باز هم متشکر