الگوریتم های ریاضی در برنامه نویسی گرافیک

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام
رابطه ی رنگ های RGB چجوری هه؟
مثلا یه رنگ به ترتیب RGB بصورت 50 و 210 و 228 داشته باشیم ، وقتی یکی شون تغییر کنه مثلا G که 210 هست ، بشه 220 ، اون دو تا چند میشن؟ یا هر عدد مختلف دیگه ای مثلا 10 بشه ، اون دو تا چند میشن؟ یا اون دو تا تغییر کنن ، این چند میشه؟ کلا رابطه شونو چجوری میشه بدست آورد؟
کلا هدفم اینه که وقتی یک رنگ انتخاب شد ، بازه ی کم رنگ و پر رنگ از همون رنگ رو تشخیص بدم

-------------------------

نکته ی تکمیلی بگم :
منظورم انتخاب یک رنگِ انتخاب شده (مثلا همون رنگ که گفتم) و تغییر اون رنگ بین سفید (سوق دادن هر سه RGB به رنگ سفید یعنی 255 و) رنگ سیاه (یعنی 0) هست
در واقع ، هر رنگی که داریم ، کم رنگ تر اش (مایل به سفید) و تیره تر اش (مایل به سیاه) را انتخاب کنیم ، در این صورت ، هر 3 تای RGB به یک نسبت تغییر میکنه .
حالا من رابطه ی این نسبیت رو میخوام
 
آخرین ویرایش:

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
تازه فهمیدم اون Saturation هه که دنبالشم

----------------------------------------------------------

خود کلاس Color که متد GetSaturation داره که :green:
متدهای GetSaturation و GetHue و GetBrightness (بجای Luminance) رو داره
 
آخرین ویرایش:

the_king

مدیرکل انجمن
سلام
رابطه ی رنگ های RGB چجوری هه؟
مثلا یه رنگ به ترتیب RGB بصورت 50 و 210 و 228 داشته باشیم ، وقتی یکی شون تغییر کنه مثلا G که 210 هست ، بشه 220 ، اون دو تا چند میشن؟ یا هر عدد مختلف دیگه ای مثلا 10 بشه ، اون دو تا چند میشن؟ یا اون دو تا تغییر کنن ، این چند میشه؟ کلا رابطه شونو چجوری میشه بدست آورد؟
کلا هدفم اینه که وقتی یک رنگ انتخاب شد ، بازه ی کم رنگ و پر رنگ از همون رنگ رو تشخیص بدم

کاملا مستقل ئه، تغییر کردن مقدار G هیچ تاثیری روی B و R نداره و بالعکس.


تازه فهمیدم اون Saturation هه که دنبالشم

----------------------------------------------------------

خود کلاس Color که متد GetSaturation داره که :green:
متدهای GetSaturation و GetHue و GetBrightness (بجای Luminance) رو داره
Luminance با Brightness فرق داره ها، Luminance شدت روشنایی رنگ ئه ولی Brightness میانگین بین حداقل و حداکثر مقادیر بین R و G و B که ممکنه برای دو رنگی با شدت روشنایی های متفاوت یکسان باشه.
اساسا Brightness به روشنایی ربطی نداره چون تاثیر R و G و B روی روشنی یکسان نیست، برای همینه که ضریب شون در Luminance فرق می کنه. Brightness میگه تقریبا چقدر سفید قاطی این رنگه، نه اینکه چقدر روشنه.
کد:
Luminance = 0.299 * R + 0.587 * G + 0.114 * B
Brightness = (Min(R, G, B) + Max(R, G, B)) / 2
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
کاملا مستقل ئه، تغییر کردن مقدار G هیچ تاثیری روی B و R نداره و بالعکس.

Luminance با Brightness فرق داره ها، Luminance شدت روشنایی رنگ ئه ولی Brightness میانگین بین حداقل و حداکثر مقادیر بین R و G و B که ممکنه برای دو رنگی با شدت روشنایی های متفاوت یکسان باشه.
اساسا Brightness به روشنایی ربطی نداره چون تاثیر R و G و B روی روشنی یکسان نیست، برای همینه که ضریب شون در Luminance فرق می کنه. Brightness میگه تقریبا چقدر سفید قاطی این رنگه، نه اینکه چقدر روشنه.
کد:
Luminance = 0.299 * R + 0.587 * G + 0.114 * B
Brightness = (Min(R, G, B) + Max(R, G, B)) / 2

سلام
ممنون استاد علی
آها فرق دارن
اون اعداد ثابت چیه که در Luminance ضرب شده؟ اینا فرمول بدست آوردن Luminance و Brightness هستن؟
ببینین فرمول Brightness در بالا رو این طور که توضیح میدم و متوجه شدم ، آیا درسته؟ :
اینکه مثلا R = 50 و G = 210 و B = 228 داریم ، توی اینا باید ببینیم کدوم اعداد بزرگتر و کوچیکتر از همه هستن و بعد جواب میشه :

کد:
(50+228)/2
درسته؟
ولی فرمول Luminance رو متوجه نشدم . همون اعداد ثابتی که دادین ، باید در R و G و B ضرب بشه تا مقدارش بدست بیاد؟ اگه آره ، اون اعداد ثابت چی هستن و چرا اون اعداد؟
سئوال بعدی اینکه چرا توی کلاس Color ، توابع GetSaturation و GetHue و GetBrightness ، فقط قابلیت Get دارن و ست نمیکنن؟ یعنی مثل Luminance و Brightness ، فرمول محاسبه ی Saturation و Hue رو هم میدین تا بتونم مقدار این دو در پیکسلی را محاسبه کنم؟
و سئوال مهم اینه که حالا مثلا فرمول Brightness را حساب کردم ، بخوام با متد SetPixel (در کلاس بیت مپ) اونو در پسکسلی اِعمال کنم ، آخرش باید مقدار ARGB را داشته باشم . یعنی این فرمول ها در نهایت باید بتونه مقدار ARGB را تغییر بده . اینو چی کار کنم؟
ممنون
 

the_king

مدیرکل انجمن
سلام
ممنون استاد علی
آها فرق دارن
اون اعداد ثابت چیه که در Luminance ضرب شده؟ اینا فرمول بدست آوردن Luminance و Brightness هستن؟
ببینین فرمول Brightness در بالا رو این طور که توضیح میدم و متوجه شدم ، آیا درسته؟ :
اینکه مثلا R = 50 و G = 210 و B = 228 داریم ، توی اینا باید ببینیم کدوم اعداد بزرگتر و کوچیکتر از همه هستن و بعد جواب میشه :

کد:
(50+228)/2
درسته؟

درسته. در مورد هر فرمولی شک کردید کدش رو با .NET Reflector یا ILSpy و ... در متد های NET. ببینید.
ولی فرمول Luminance رو متوجه نشدم . همون اعداد ثابتی که دادین ، باید در R و G و B ضرب بشه تا مقدارش بدست بیاد؟ اگه آره ، اون اعداد ثابت چی هستن و چرا اون اعداد؟
بله دیگه. به فیزیک و شیمی ربطه داره، میزان تاثیر طیف نوری با طول موج های مختلف روی یاخته های عصبی چشم انسان ئه که نور رو تشخیص میده. ضرایب هم بی حساب و کتاب نیست، ضرایب استاندارد تلویزیونی ITU-R BT.601 یا CCIR 601 ئه.

سئوال بعدی اینکه چرا توی کلاس Color ، توابع GetSaturation و GetHue و GetBrightness ، فقط قابلیت Get دارن و ست نمیکنن؟ یعنی مثل Luminance و Brightness ، فرمول محاسبه ی Saturation و Hue رو هم میدین تا بتونم مقدار این دو در پیکسلی را محاسبه کنم؟
ممنون
اساسا فرمول ها یک طرفه است، چون اینها صرفا یک پارامتر ئه، فرضا شما با Hue یا Brightness خالی که نمی توانید رنگی بسازید که Set داشته باشند.
فرمول ها رو در اینترنت راحت میتوانید جستجو کنید :
RGB to HSL color conversion
Color Converter
و سئوال مهم اینه که حالا مثلا فرمول Brightness را حساب کردم ، بخوام با متد SetPixel (در کلاس بیت مپ) اونو در پسکسلی اِعمال کنم ، آخرش باید مقدار ARGB را داشته باشم . یعنی این فرمول ها در نهایت باید بتونه مقدار ARGB را تغییر بده . اینو چی کار کنم؟

من اصلا نمیدونم شما دارید چیکار می کنید، Brightness چیزی نیست که روی یک پیکسل اعمال بشه، منظورتون رو باید مشخص کنید. Brightness یک پارامتر ئه، مثل وزن ئه. که فرضا وزن این آقا 85 کیلو ئه. اینکه بگید Brightness رو اعمال کنم مثل اینه که بگید من میخوام وزن 70 کیلو رو روی این آقا اعمال کنم، این معنی نداره. شما می توانید به Brightness چیزی اضافه یا کم کنید، یعنی R و G و B یک پیکسل رو بگیرید و هر کدوم رو با عدد مثبت یا منفی ای جمع کنید و اگر از 255 بیشتر یا از 0 کمتر شدند به 255 و 0 تغییر بدید (چون محدوده RGBA بایتی ئه) و بعد با ()Color.FromArgb بر اساس اون مقادیر رنگ جدیدی بسازید که روشن تر یا تیره تر شده.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
درسته. در مورد هر فرمولی شک کردید کدش رو با .NET Reflector یا ILSpy و ... در متد های NET. ببینید.

بله دیگه. به فیزیک و شیمی ربطه داره، میزان تاثیر طیف نوری با طول موج های مختلف روی یاخته های عصبی چشم انسان ئه که نور رو تشخیص میده. ضرایب هم بی حساب و کتاب نیست، ضرایب استاندارد تلویزیونی ITU-R BT.601 یا CCIR 601 ئه.


اساسا فرمول ها یک طرفه است، چون اینها صرفا یک پارامتر ئه، فرضا شما با Hue یا Brightness خالی که نمی توانید رنگی بسازید که Set داشته باشند.
فرمول ها رو در اینترنت راحت میتوانید جستجو کنید :
RGB to HSL color conversion
Color Converter


من اصلا نمیدونم شما دارید چیکار می کنید، Brightness چیزی نیست که روی یک پیکسل اعمال بشه، منظورتون رو باید مشخص کنید. Brightness یک پارامتر ئه، مثل وزن ئه. که فرضا وزن این آقا 85 کیلو ئه. اینکه بگید Brightness رو اعمال کنم مثل اینه که بگید من میخوام وزن 70 کیلو رو روی این آقا اعمال کنم، این معنی نداره. شما می توانید به Brightness چیزی اضافه یا کم کنید، یعنی R و G و B یک پیکسل رو بگیرید و هر کدوم رو با عدد مثبت یا منفی ای جمع کنید و اگر از 255 بیشتر یا از 0 کمتر شدند به 255 و 0 تغییر بدید (چون محدوده RGBA بایتی ئه) و بعد با ()Color.FromArgb بر اساس اون مقادیر رنگ جدیدی بسازید که روشن تر یا تیره تر شده.

ممنون استاد علی
چرا HSL یا Brightness ، به یک پیکسل ،اِعمال شدنی نیست؟
مثلا درفتوشاپ ، saturation رنگ را بالا میبرن ، خوب فتوشاپ اول میاد رنگ اون پیکسل را میگیره و بعد میزان saturation اش را تا 240 (اگه تا آخر ببریم) افزایش میده و توی اون پیکسل اِعمال میکنه دیگه
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
فهمیدم
کلاس HslColor Class این کار رو میکنه
نمیدونستم برای کار با HSL ، کلاسی مجزا وجود داره
ممنون
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
ولی مشکلش اینه که توی راهنماش نوشته در اسمبلی Microsoft.VisualStudio.Modeling.Sdk.12.0.dll و در فضای نام Microsoft.VisualStudio.Modeling.Diagrams هست .
این اسمبلی را پیدا نکردم . اسمبلی Microsoft.VisualStudio.Modeling.SDK.Integration.15.0 و Microsoft.VisualStudio.Modeling.SDK.Integration.Shell.15.0 بود که توی اینها هم کلاسی بنام HslColor نبودن . فضای نام Microsoft.VisualStudio.Modeling بود اما بعدش فضای نامِ Diagrams نبود که توش کلاس HslColor را ببینم یا نبینم . بجای فضای نام Diagrams ، فضای نام Integration بود
توی پوشه ی C:\Program Files (x86)\Reference Assemblies رو هم گشتم ولی فایلی بنام Microsoft.VisualStudio.Modeling.Sdk.12.0.dll پیدا نکردم
چی کار باید کنم؟
 

the_king

مدیرکل انجمن
کد:
        [DllImport("shlwapi.dll")]
        private static extern int ColorHLSToRGB(short wHue, short wLuminance, short wSaturation);

        [DllImport("shlwapi.dll")]
        private static extern void ColorRGBToHLS(int clrRGB, ref short pwHue, ref short pwLuminance, ref short pwSaturation);

            var c = Color.FromArgb(ColorHLSToRGB(50, 100, 150));
            short h = 0, s = 0, l = 0;
            ColorRGBToHLS(c.ToArgb(), ref h, ref l, ref s);
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
کد:
        [DllImport("shlwapi.dll")]
        private static extern int ColorHLSToRGB(short wHue, short wLuminance, short wSaturation);

        [DllImport("shlwapi.dll")]
        private static extern void ColorRGBToHLS(int clrRGB, ref short pwHue, ref short pwLuminance, ref short pwSaturation);

            var c = Color.FromArgb(ColorHLSToRGB(50, 100, 150));
            short h = 0, s = 0, l = 0;
            ColorRGBToHLS(c.ToArgb(), ref h, ref l, ref s);

او
API Reference بود . فکر کردم اعضای دات نت هه
اصلا حواسم نبود . ببخشید
اون نام shlwapi.dll رو از کجا آوردین؟ توی سایتش نوشته نام اسمبلی اش Microsoft.VisualStudio.Modeling.Sdk.12.0.dl هه که . هر چند من پیداش نکردم
ورودی هایی هم که برای دو متدِ ColorHLSToRGB و ColorRGBToHLS دادین ، شبیه ورودی های متدهای زیر نیست :
https://msdn.microsoft.com/en-us/li....modeling.diagrams.hslcolor.fromrgbcolor.aspx
و
HslColor.ToRgbColor Method (Microsoft.VisualStudio.Modeling.Diagrams)
این ورودی ها از کجا اومدن؟
ممنون
 
آخرین ویرایش:

the_king

مدیرکل انجمن
او
API Reference بود . فکر کردم اعضای دات نت هه
اصلا حواسم نبود . ببخشید
اون نام shlwapi.dll رو از کجا آوردین؟ توی سایتش نوشته نام اسمبلی اش Microsoft.VisualStudio.Modeling.Sdk.12.0.dl هه که . هر چند من پیداش نکردم
ورودی هایی هم که برای دو متدِ ColorHLSToRGB و ColorRGBToHLS دادین ، شبیه ورودی های متدهای زیر نیست :
HslColor.FromRgbColor Method (Color) (Microsoft.VisualStudio.Modeling.Diagrams)
و
HslColor.ToRgbColor Method (Microsoft.VisualStudio.Modeling.Diagrams)
این ورودی ها از کجا اومدن؟
ممنون
Modeling SDK یک چیزه، Shlwapi یک چیز دیگه. Shlwapi از زمان ویندوز 95 هم جزئی از Shell اصلی ویندوز بوده. کتابخانه ای نیست که بعدا به ویندوز اضافه بشه.
ویژوال استدیو یه مجموعه اختیاری Visual Studio Extensibility Tools یا به عبارتی Visual Studio SDK داره که موقع نصب شدن باید انتخاب بشه و این Modeling SDK for Microsoft Visual Studio جزئی از اونه که حقیقتا هم برای اینجور موارد بهش نیازی ندارید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
Modeling SDK یک چیزه، Shlwapi یک چیز دیگه. Shlwapi از زمان ویندوز 95 هم جزئی از Shell اصلی ویندوز بوده. کتابخانه ای نیست که بعدا به ویندوز اضافه بشه.
ویژوال استدیو یه مجموعه اختیاری Visual Studio Extensibility Tools یا به عبارتی Visual Studio SDK داره که موقع نصب شدن باید انتخاب بشه و این Modeling SDK for Microsoft Visual Studio جزئی از اونه که حقیقتا هم برای اینجور موارد بهش نیازی ندارید.

آها ممنون استاد علی
چون من فعلا بیشتر تاکید میکنم که منبع دات نت باشه ، نه اینکه من مشکل استفاده اشته باشم ، چون توی آموزش ها ، فعلا به مبحث استفاده از منابع غیر دات نت نرسیدم
نسخه ام 2017 هه . اگه اینی که گفتین را نصب کنم (البته فکر کنم توی ستاپ داره ولی لینک دانلود مجزاش رو برای نسخه ی 2017 گیر نیاوردم) ، طبق لینک زیر :
The Visual Studio Modeling SDK is now available with Visual Studio 2017 – Microsoft DevOps Blog
برای استفاده ، بجای اینکه از قسمت Windows Classic Desktop استفاده کنم ، باید در قسمت Extensibility برم؟ یا اینکه توی winform هم که باشم و فایل Microsoft.VisualStudio.Modeling.Sdk.12.0.dll رو refrence کنم ، برای استفاده از کلاس HslColor Class کافی هه
 

the_king

مدیرکل انجمن
آها ممنون استاد علی
چون من فعلا بیشتر تاکید میکنم که منبع دات نت باشه ، نه اینکه من مشکل استفاده اشته باشم ، چون توی آموزش ها ، فعلا به مبحث استفاده از منابع غیر دات نت نرسیدم
نسخه ام 2017 هه . اگه اینی که گفتین را نصب کنم (البته فکر کنم توی ستاپ داره ولی لینک دانلود مجزاش رو برای نسخه ی 2017 گیر نیاوردم) ، طبق لینک زیر :
The Visual Studio Modeling SDK is now available with Visual Studio 2017 – Microsoft DevOps Blog
برای استفاده ، بجای اینکه از قسمت Windows Classic Desktop استفاده کنم ، باید در قسمت Extensibility برم؟ یا اینکه توی winform هم که باشم و فایل Microsoft.VisualStudio.Modeling.Sdk.12.0.dll رو refrence کنم ، برای استفاده از کلاس HslColor Class کافی هه
برای کاری که شما میخواهید بکنید فقط با Add Reference اضافه اش کنید. در ضمن کار جالبی نیست که برای یک همچین تبدیل ساده ای همچین کمپوننتی رو که به یه عالمه کلاس دیگه وابسته است رو اضافه کنید. جزو NET. هم نیست که همراه Framework روی همه سیستم ها از قبل موجود باشه. شما هم کلا فقط یک تبدیل HSL RGB اش رو می خواهید. بهتره کدش رو با NET Reflector. یا ILSpy ببینید و از رویش برای خودتون نمونه مشابه بسازید :
کد:
public static HslColor FromRgbColor(Color color)
{
    HslColor hslColor = new HslColor();
    int num = (int)Math.Max(Math.Max(color.R, color.G), color.B);
    int num2 = (int)Math.Min(Math.Min(color.R, color.G), color.B);
    hslColor.Luminosity = ((num + num2) * 240 + 255) / 510;
    if (num == num2)
    {
        hslColor.Saturation = 0;
        hslColor.Hue = 160;
    }
    else
    {
        if (hslColor.Luminosity <= 120)
        {
            hslColor.Saturation = ((num - num2) * 240 + (num + num2) / 2) / (num + num2);
        }
        else
        {
            hslColor.Saturation = ((num - num2) * 240 + (510 - num - num2) / 2) / (510 - num - num2);
        }
        int num3 = ((num - (int)color.R) * 40 + (num - num2) / 2) / (num - num2);
        int num4 = ((num - (int)color.G) * 40 + (num - num2) / 2) / (num - num2);
        int num5 = ((num - (int)color.B) * 40 + (num - num2) / 2) / (num - num2);
        int num6;
        if ((int)color.R == num)
        {
            num6 = num5 - num4;
        }
        else if ((int)color.G == num)
        {
            num6 = 80 + num3 - num5;
        }
        else
        {
            num6 = 160 + num4 - num3;
        }
        if (num6 < 0)
        {
            hslColor.Hue = num6 + 240;
        }
        else if (num6 > 240)
        {
            hslColor.Hue = num6 - 240;
        }
        else
        {
            hslColor.Hue = num6;
        }
    }
    return hslColor;
}
کد:
public Color ToRgbColor()
{
    int red = 0;
    int green = 0;
    int blue = 0;
    if (this.luminosity != 0)
    {
        if (this.saturation == 0)
        {
            green = (blue = (red = this.luminosity * 255 / 240));
        }
        else
        {
            int num;
            if (this.luminosity <= 120)
            {
                num = (this.luminosity * (240 + this.saturation) + 120) / 240;
            }
            else
            {
                num = this.luminosity + this.saturation - (this.luminosity * this.saturation + 120) / 240;
            }
            int expr_8D = 2 * this.luminosity - num;
            red = HslColor.HueToRgb(expr_8D, num, this.hue + 80);
            green = HslColor.HueToRgb(expr_8D, num, this.hue);
            blue = HslColor.HueToRgb(expr_8D, num, this.hue - 80);
        }
    }
    return Color.FromArgb(red, green, blue);
}
یا از همون API ویندوز کمک بگیرید.
 

the_king

مدیرکل انجمن
کد:
private static int HueToRgb(int m1, int m2, int hue)
{
    if (hue < 0 && hue + 240 >= hue)
    {
        hue += 240;
    }
    if (hue > 240 && hue - 240 <= hue)
    {
        hue -= 240;
    }
    int num;
    if (6 * hue < 240)
    {
        num = m1 + ((m2 - m1) * hue + 20) / 40;
    }
    else if (2 * hue < 240)
    {
        num = m2;
    }
    else if (3 * hue < 480)
    {
        num = m1 + ((m2 - m1) * (160 - hue) + 20) / 40;
    }
    else
    {
        num = m1;
    }
    return (num * 255 + 120) / 240;
}
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
ممنون استاد علی
پیرو سودوکدی که برای blur گفته بودین ، اول میخوام یه الگوریتمی بنویسم که مثلا به اون تابع 4 رو دادیم ، 4 تا 4 تا پیکسل های کنار هم را انتخاب کنه و در یک آرایه بریزه . در واقع دو تا از سطر و دو تا از ستون که پیکسل هاش کنار هم هستن را انتخاب کنه و در آرایه ای بریزه
الگوریتم زیر را نوشتم ، y اش تا سطر 2 میره ، درست کار میکنه ولی از سطر سوم ، قاتی میکنه و توی ایندکس صفر ام آرایه (دیکشنری) (و همینطور ایندکس های بعدیش) ، خیلی بیشتر از 4 عضو میریزه


کد:
        private void button60_Click(object sender, EventArgs e)
        {
            foreach (KeyValuePair<int, List<Point>> item in this.FillBlurMemory(4))
            {
                foreach (Point point in item.Value)
                {
                    MessageBox.Show("index : " + item.Key + "\n\npoint : " + point);
                }
              
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="numPixelBlur"> تعداد پیکسل هایی که باید تار بشن . این عدد باید عدد رادیکالی باشه </param>
        /// <returns> </returns>
        private Dictionary<int, List<Point>> FillBlurMemory(int numPixelBlur)
        {
            Dictionary<int, List<Point>> blurMemory = new Dictionary<int, List<Point>>();
            // تعداد پیکسل هایی که در هر سطر باید تار بشن
            int numPixInRow = Convert.ToInt32(Math.Sqrt(numPixelBlur)); // 2
            int indexBlurMemory = 0;  // شماره ی ایندکس و کلید ، در حافظه ی دیکشنری .
            int numMemoryElement = 0;
            int forward = 0;
            Bitmap bitmapTemp = new Bitmap(6, 4);

            for (int y = 0; y < bitmapTemp.Height; y++)
            {
                int orbitInY = y % numPixInRow;
                for (int x = 0; x < bitmapTemp.Width; x++)
                {
                    indexBlurMemory = x / numPixInRow;

                    int orbitInX = x % numPixInRow;  // به اندازه ی رادیکال ، دور میزنه
                    if (x >= bitmapTemp.Width - numPixInRow && orbitInY == numPixInRow - 1)
                    {
                        numMemoryElement = blurMemory.Keys.Count - 1;
                        forward = 1;
                    }

                    if (orbitInY == 0)
                        indexBlurMemory = forward + ( ((numMemoryElement * 2) + x) / numPixInRow);
                  
                  
                    if (orbitInX == 0 && orbitInY == 0)
                        blurMemory[indexBlurMemory] = new List<Point>();

                    blurMemory[indexBlurMemory].Add(new Point(x, y));
                }
            }


            return blurMemory;
        }

چجوری میشه درستش کرد و کلا چه الگوریتمی برای این کار پیشنهاد میدین؟
ممنون
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
به زر و به زور درست شد :

کد:
        private Dictionary<int, List<Point>> FillBlurMemory(int numPixelBlur)
        {
            Dictionary<int, List<Point>> blurMemory = new Dictionary<int, List<Point>>();
            // تعداد پیکسل هایی که در هر سطر باید تار بشن
            int numPixInRow = Convert.ToInt32(Math.Sqrt(numPixelBlur)); // 2
            int indexBlurMemory = 0;  // شماره ی ایندکس و کلید ، در حافظه ی دیکشنری .
            int numMemoryElement = 0;

            for (int y = 0; y < this.BitmapMain.Height; y++)
            {
                int orbitInY = y % numPixInRow;
                for (int x = 0; x < this.BitmapMain.Width; x++)
                {
                    indexBlurMemory = x / numPixInRow;

                    int orbitInX = x % numPixInRow;  // به اندازه ی رادیکال ، دور میزنه
                    if(x == 0 && orbitInY == 0)
                        numMemoryElement = blurMemory.Keys.Count;

                    indexBlurMemory = (((numMemoryElement * 2) + x) / numPixInRow);
                 
                    if (orbitInX == 0 && orbitInY == 0)
                        blurMemory[indexBlurMemory] = new List<Point>();

                    blurMemory[indexBlurMemory].Add(new Point(x, y));
                }
            }
         
            return blurMemory;
        }

عدد 9 را به عنوان ورودی تابع میدم ، دیکشنری تا عضو 235 میره و ارور میده . دیگه قاتی کردم این قدر باهاش کار کردم . ولی با ورودیِ عددِ 4 مشکلی نداره
ولی الگوریتم بهتر از این رو نمیدونم . البته یه الگوریتم جایگزین دیگه توی ذهنم هست (شبیه اون چیزی که پارسال برای الگوریتم اسب در شطرنج (که کدش رو در صفحه ی 9 تاپیک گفتگوی سی شارپ گذاشتم) بکار بردم)
 
آخرین ویرایش:

the_king

مدیرکل انجمن
ممنون استاد علی
پیرو سودوکدی که برای blur گفته بودین ، اول میخوام یه الگوریتمی بنویسم که مثلا به اون تابع 4 رو دادیم ، 4 تا 4 تا پیکسل های کنار هم را انتخاب کنه و در یک آرایه بریزه . در واقع دو تا از سطر و دو تا از ستون که پیکسل هاش کنار هم هستن را انتخاب کنه و در آرایه ای بریزه
الگوریتم زیر را نوشتم ، y اش تا سطر 2 میره ، درست کار میکنه ولی از سطر سوم ، قاتی میکنه و توی ایندکس صفر ام آرایه (دیکشنری) (و همینطور ایندکس های بعدیش) ، خیلی بیشتر از 4 عضو میریزه


چجوری میشه درستش کرد و کلا چه الگوریتمی برای این کار پیشنهاد میدین؟
ممنون
کد تون خیلی بی ربطه. درست کردنی نیست، این چیزی که نوشتید رو بذارید کنار از نو رویش فکر کنید. دیکشنری و Point اصلا اینجا کاربردی نداره. شما به Point کاری ندارید شما از رنگ باید میانگین بگیرید، پیکسل ها نه پراکنده اند و نه جابجا می شوند که بخواهید جایی ثبت شون کنید.
روی یک کاغذ یک ماتریس مثلا 5 در 5 رو با اعداد تصادفی پر کنید و فرض کنید اصلا رنگ ها یک پارامتر ای اند، مثلا سیاه و سفید هستند و این اعداد مثلا R یا G پیکسل ها است، فرقی نمی کنه که، شما برای R هر کدی بنویسید برای G و B هم مثل همون کد ئه. بعد ببینید تو یک ماتریس 5 در 5 دیگه که قراره محو اش باشه، چطوری میانگین 9 نقطه مجاور (3x3) هر پیکسل رو جداگانه حساب می کنید و در پیکسل قرار می دهید. طبعا برای پیکسل های لبه تعداد نمونه ها کمتر از 9 ئه، اما حالا برای سادگی فعلا فرض کنید که روی پیکسل های لبه محو انجام نمیدید. هیچ منطقی هم نداره که لیست و دیکشنری و ... بخواد. شما یک ماتریس رو دارید در یک ماتریس دیگه محو می کنید. موقعیت نقطه ای که هر لحظه محو می کنید مشخصه، مجاور هاش هم از x - 1, y - 1 شروع میشه تا x + 1, y + 1 . که اونم با x + i و y + j می توانید با حلقه های تو در تو بنویسید. نه لزومی داره که این Point ها رو جایی لیست کنید و نه Forward ای چیزی میخواد.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
کد تون خیلی بی ربطه. درست کردنی نیست، این چیزی که نوشتید رو بذارید کنار از نو رویش فکر کنید. دیکشنری و Point اصلا اینجا کاربردی نداره. شما به Point کاری ندارید شما از رنگ باید میانگین بگیرید، پیکسل ها نه پراکنده اند و نه جابجا می شوند که بخواهید جایی ثبت شون کنید.
روی یک کاغذ یک ماتریس مثلا 5 در 5 رو با اعداد تصادفی پر کنید و فرض کنید اصلا رنگ ها یک پارامتر ای اند، مثلا سیاه و سفید هستند و این اعداد مثلا R یا G پیکسل ها است، فرقی نمی کنه که، شما برای R هر کدی بنویسید برای G و B هم مثل همون کد ئه. بعد ببینید تو یک ماتریس 5 در 5 دیگه که قراره محو اش باشه، چطوری میانگین 9 نقطه مجاور (3x3) هر پیکسل رو جداگانه حساب می کنید و در پیکسل قرار می دهید. طبعا برای پیکسل های لبه تعداد نمونه ها کمتر از 9 ئه، اما حالا برای سادگی فعلا فرض کنید که روی پیکسل های لبه محو انجام نمیدید. هیچ منطقی هم نداره که لیست و دیکشنری و ... بخواد. شما یک ماتریس رو دارید در یک ماتریس دیگه محو می کنید. موقعیت نقطه ای که هر لحظه محو می کنید مشخصه، مجاور هاش هم از x - 1, y - 1 شروع میشه تا x + 1, y + 1 . که اونم با x + i و y + j می توانید با حلقه های تو در تو بنویسید. نه لزومی داره که این Point ها رو جایی لیست کنید و نه Forward ای چیزی میخواد.

ممنون استاد علی
کدِ پست بالا که گذاشتم رو ببینید
چرا پیکسل ها پراکنده نیستن؟ گفتین اون پیکسل هایی که کنار هم هستن رو میانگین R و G و B شون رو بگیرم . خوب مثلا دو پیکسل در راستای محور x (مثلا با مختصات 0, 0 و 1, 0) به همراه دو پیکسلِ زیرش در راستای محور y (مثلا با مختصات 0, 1 و 1, 1) . چهار تا پیکسلِ بعدی مثلا از مختصات نقطه ی 2, 2 شروع میشه (باز هم 2 تا در راستای x و 2 تا هم در راستای y) و همین روال ادامه داره
منظورتون از ماتریکس ، آرایه ی دو بعدی هه ؟ وگرنه من قضیه ی ماتریکس توی ریاضیات را بلد نیستم
کلا اگه این روالی که در خط بالا توضیح دادم (انتخاب پیکسل های کنار هم) ، منظورتون این نیست و من اشتباه متوجه شدم ، بی زحمت توی شکل نشون میدین که مراحل کلی کار چیه؟ چون من با شکل خیلی قشنگ تر متوجه میشم
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
کد تقریبی این شد (البته محدودیت هاش و مشکلات احتمالی اش به کنارچون در حد تمرین هه) :

کد:
        private void button60_Click(object sender, EventArgs e)
        {
            this.HideFormControls();
           

            foreach (KeyValuePair<int, List<Point>> bitmapPixels in this.FillBlurMemory(4))  // bitmap iterator
            {
                int[,] colorElement = new int[4, 3];

                for (int counterPixel = 0; counterPixel < bitmapPixels.Value.Count; counterPixel++) // 4 pixel iterator
                {
                    int x = bitmapPixels.Value[counterPixel].X;
                    int y = bitmapPixels.Value[counterPixel].Y;
                    Color pixelColor = this.BitmapMain.GetPixel(x, y);
                    int[] pixelColorRGBArray = new int[] { pixelColor.R, pixelColor.G, pixelColor.B };

                    for (int i = 0; i < colorElement.GetLength(1); i++)  // RGB iterator
                        colorElement[counterPixel, i] = pixelColorRGBArray[i];

                }

                int[] mianginRGB = new int[3] {0, 0, 0 };
                for (int counterRGB = 0; counterRGB < colorElement.GetLength(1); counterRGB++)  // RGB iterator For Miangin & Fill
                {
                    for (int counterPixel = 0; counterPixel < colorElement.GetLength(0); counterPixel++) // 4 bar baraye 4 pixel
                    {
                        if (counterRGB > 2 || counterPixel > 3)
                        {
                            int a = 0;
                        }
                        mianginRGB[counterRGB] += colorElement[counterPixel, counterRGB];
                    }
                       

                    mianginRGB[counterRGB] = mianginRGB[counterRGB] / 4;
                }

                for (int counterPixel = 0; counterPixel < colorElement.GetLength(0); counterPixel++) // 4 pixel iterator For Set Pixel RGB
                {
                    int x = bitmapPixels.Value[counterPixel].X;
                    int y = bitmapPixels.Value[counterPixel].Y;
                    this.BitmapMain.SetPixel(x, y, Color.FromArgb(255, mianginRGB[0], mianginRGB[1], mianginRGB[2]));
                }
            }

        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="numPixelBlur"> تعداد پیکسل هایی که باید تار بشن . این عدد باید عدد رادیکالی باشه </param>
        /// <returns> </returns>
        private Dictionary<int, List<Point>> FillBlurMemory(int numPixelBlur)
        {
            Dictionary<int, List<Point>> blurMemory = new Dictionary<int, List<Point>>();
            // تعداد پیکسل هایی که در هر سطر باید تار بشن
            int numPixInRow = Convert.ToInt32(Math.Sqrt(numPixelBlur)); // 2
            int indexBlurMemory = 0;  // شماره ی ایندکس و کلید ، در حافظه ی دیکشنری .
            int numMemoryElement = 0;

            for (int y = 0; y < this.BitmapMain.Height; y++)
            {
                int orbitInY = y % numPixInRow;
                for (int x = 0; x < this.BitmapMain.Width; x++)
                {
                    indexBlurMemory = x / numPixInRow;

                    int orbitInX = x % numPixInRow;  // به اندازه ی رادیکال ، دور میزنه
                    if(x == 0 && orbitInY == 0)
                        numMemoryElement = blurMemory.Keys.Count;

                    indexBlurMemory = (((numMemoryElement * 2) + x) / numPixInRow);
                   
                    if (orbitInX == 0 && orbitInY == 0)
                        blurMemory[indexBlurMemory] = new List<Point>();

                    blurMemory[indexBlurMemory].Add(new Point(x, y));
                }
            }
           
            return blurMemory;
        }

this.BitmapMain هم یک فایل تصویر هه که لود شد
ولی بیشتر شطرنجی شد تا اینکه تار بشه
 

the_king

مدیرکل انجمن
ممنون استاد علی
کدِ پست بالا که گذاشتم رو ببینید
چرا پیکسل ها پراکنده نیستن؟ گفتین اون پیکسل هایی که کنار هم هستن رو میانگین R و G و B شون رو بگیرم . خوب مثلا دو پیکسل در راستای محور x (مثلا با مختصات 0, 0 و 1, 0) به همراه دو پیکسلِ زیرش در راستای محور y
(مثلا با مختصات 0, 1 و 1, 1) . چهار تا پیکسلِ بعدی مثلا از مختصات نقطه ی 2, 2 شروع میشه (باز هم 2 تا در راستای x و 2 تا هم در راستای y) و همین روال ادامه داره
اینی که میگید پراکنده است؟ نقاطی که قراره ازشون میانگین بشه داخل یک محیط مربعی هستند با طول و عرض مشخص. اینکه پراکنده نیست. تصادفی که نقاط رو انتخاب نمی کنید که پراکنده باشند.
منظورتون از ماتریکس ، آرایه ی دو بعدی هه ؟ وگرنه من قضیه ی ماتریکس توی ریاضیات را بلد نیستم
کلا اگه این روالی که در خط بالا توضیح دادم (انتخاب پیکسل های کنار هم) ، منظورتون این نیست و من اشتباه متوجه شدم ، بی زحمت توی شکل نشون میدین که مراحل کلی کار چیه؟ چون من با شکل خیلی قشنگ تر متوجه میشم

ماتریس رو آرایه دو بعدی فرض کنید اما واقعا آرایه دو بعدی ندارید در Bitmap . شما با GetPixel و SetPixel موقعیت x و y می دهید. می توانید فرض کنید پشت اش یک آرایه دو بعدی ئه اما نیست، حافظه اش تک بعدی ئه.
blur.png
 

جدیدترین ارسال ها

بالا