الصلب نحو أو بعيدًا عن اللون بنسبة مئوية معينة

StackOverflow https://stackoverflow.com/questions/3097753

  •  29-09-2019
  •  | 
  •  

سؤال

أحاول محاكاة تأثير الصبغة من Open XML. ما تفعله هو تغيير لون البكسل في صورة عن طريق تحويل اللون. يستغرق 2 معلمات: 1) hue (بالدرجات) و 2) amt (المبلغ ، نسبة مئوية). إنه رقم 2 أواجه مشكلات معها. تنص المواصفات:

لون: تحول تأثير قيم الألوان إما نحو أو بعيدًا عن اللون من خلال المبلغ المحدد.

  • AMT (المبلغ) - يحدد بمقدار قيمة اللون.
  • مسحة (Hue) - يحدد الصبغ الذي يجب أن تلميح.

لا تمانع في بناء XML ، يمكنني محاكاة القيم التي تحتوي على amt من 100 ٪. على سبيل المثال ، إذا أردت اللون الأزرق (Hue: 240 °) ، يمكنني إنشاء هذا ( ملون واحد). هذا مثال:

إبداعي و ملون (Hue = 240 ، المبلغ = 100 ٪).
Original Modified

يتم تحقيق ذلك ببساطة عن طريق ضبط Hue إلى 240 ، مع الحفاظ على التشبع والخمياء كما هو والتحويل إلى RGB وكتابة كل بكسل.

هذا ما لا يمكنني تحقيقه على الرغم من:

Hue =240 (أزرق) ، كمية = 30%, 50% و 80%, ، على التوالى
30% 50% 80%

مرة أخرى ، المواصفات ل Amount يقول يحدد بمقدار قيمة اللون. لقد جربت كل أنواع الطرق هنا للحصول على هذا العمل ، لكن لا يمكن أن يبدو (hue=hue*amount, originalhue * amount + hue, ، إلخ.)

المزيد من الأمثلة: Hue =120 (لون أخضر) ، كمية = 30%, 50%, 80% و 100%, ، على التوالى. ال 100% واحد يمكنني الحصول عليه.
30% 50% 80% 100%

فيما يلي بعض قوائم القيمة لبكسل واحد في الصور أعلاه:

بكسل 159 ، 116 - صور زرقاء

        Hue المبلغ RGB | HSL
الأصلي 244 196 10 |  48  0.92  0.5
Blue    240     30%      237   30   45  | 356  0.85  0.52
Blue    240     50%      245    9  156  | 323  0.93  0.5
Blue    240     80%      140   12  244  | 273  0.91  0.5
Blue    240    100%       12   12  244  | 240  0.91  0.5

بكسل 159 ، 116 - صور خضراء

        Hue المبلغ RGB | HSL
الأصلي 244 196 10 |  48  0.92  0.5
Green    120     30%     211  237   30  |  68  0.85  0.52
Green    120     50%     159  237   30  |  83  0.85  0.52
Green    120     80%      81  237   29  | 105  0.85  0.52
Green    120    100%      29  237   29  | 120  0.85  0.52


لذا ، فإن السؤال هو: هل يعرف أي شخص كيف يجب أن يعمل هذا؟

ملاحظة: هذا هو ليس مكررة من:

هل كانت مفيدة؟

المحلول

أنا متأكد تمامًا من أن مشكلتك تنتج عن الطريقة التي تتداخل بها الزوايا. إليك وظيفة الاستيفاء (مكتوبة في بيثون) يجب أن تفعل الخدعة. يعتمد على اقتراح من موضوع منتديات XNA أقصر استيفاء زاوية ثنائية الأبعاد.

def wrap(value, lower, upper):
    distance = upper - lower
    return value - ((value-lower)//distance)*distance

def shortestangle(a,b):
    angle = wrap(b-a, 0, 360)
    if angle>=180: angle -= 360
    return angle

def interpolate(a,b,amount):
    return (a+shortestangle(a,b)*amount)%360

حاليا، interpolate(originalHue,hue,amount) يجب أن تنتج النتيجة المرجوة.

يحرر: أفهم أن هدفك هو تدوير اللون الأصلي نحو صبغة مستهدفة معينة بمبلغ معين. أنا متأكد من أنك على دراية بهذا بالفعل ، ولكن من أجل التوضيح ، إليك عجلة ملونة.

Color Wheel
(مصدر: sapdesignguild.org)

المشكلة هي أن الخلط (أو التداخل) زاويتان ليسوا تافهة ، لذلك مثل الكود hue = ((hue - originalHue) * amount) + originalHue لن يعمل. هناك عدد لا حصر له من الطرق التي يمكنك من خلالها الانتقال من زاوية إلى أخرى بسبب التفاف عند 360 درجة. للوصول من 0 درجة إلى 60 درجة ، يمكنك تدوير 60 درجة في اتجاه عقارب الساعة ، و 420 درجة في اتجاه عقارب الساعة ، و 300 درجة في اتجاه عقارب الساعة ، إلخ. عادة ما تكون الزاوية الأقصر هي الزاوية المطلوبة.

على سبيل المثال ، دعنا ننظر في رقاب البطريق: إذا كان اللون الأصلي الخاص بك هو 30 درجة (برتقالي) ، فإن هدفك هو 240 درجة (أزرق) والمبلغ 50 ٪ ، فستحصل على النتائج التالية:

//Linear Interpolation
(30° + (240° - 30°)*0.5) = 135° (green)

//"Shortest 2D Angle Interpolation"
(30° + shortestangle(30°,240°)*0.5) % 360 = (30° + (-150°)*0.5) % 360 = 315° (magenta)

أظن أن النتيجة الثانية هي النتيجة التي تبحث عنها ، لكنني قد أكون مخطئًا وقد يكون الخطأ في مكان آخر تمامًا ...

نصائح أخرى

يجب عليك إلقاء نظرة على tintparams في GDI+ (ليس جزءًا من .NET) - قد يكون هذا مجرد ما تبحث عنه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top