तो मैं GIMP source code में देखा ... ew! मैंने इसे सामान्य और पठनीय बना दिया। हालांकि अभी भी काफी तेज है। गणित स्पष्टीकरण के लिए Sampo's answer देखें। यहाँ सी # कार्यान्वयन (C/C++ करने के लिए आसान परिवर्तनीय) है:
static class PixelShaders {
/// <summary>
/// Generic color space color to alpha.
/// </summary>
/// <param name="pA">Pixel alpha.</param>
/// <param name="p1">Pixel 1st channel.</param>
/// <param name="p2">Pixel 2nd channel.</param>
/// <param name="p3">Pixel 3rd channel.</param>
/// <param name="r1">Reference 1st channel.</param>
/// <param name="r2">Reference 2nd channel.</param>
/// <param name="r3">Reference 3rd channel.</param>
/// <param name="mA">Maximum alpha value.</param>
/// <param name="mX">Maximum channel value.</param>
static void GColorToAlpha(ref double pA, ref double p1, ref double p2, ref double p3, double r1, double r2, double r3, double mA = 1.0, double mX = 1.0) {
double aA, a1, a2, a3;
// a1 calculation: minimal alpha giving r1 from p1
if (p1 > r1) a1 = mA * (p1 - r1)/(mX - r1);
else if (p1 < r1) a1 = mA * (r1 - p1)/r1;
else a1 = 0.0;
// a2 calculation: minimal alpha giving r2 from p2
if (p2 > r2) a2 = mA * (p2 - r2)/(mX - r2);
else if (p2 < r2) a2 = mA * (r2 - p2)/r2;
else a2 = 0.0;
// a3 calculation: minimal alpha giving r3 from p3
if (p3 > r3) a3 = mA * (p3 - r3)/(mX - r3);
else if (p3 < r3) a3 = mA * (r3 - p3)/r3;
else a3 = 0.0;
// aA calculation: max(a1, a2, a3)
aA = a1;
if (a2 > aA) aA = a2;
if (a3 > aA) aA = a3;
// apply aA to pixel:
if (aA >= mA/mX) {
pA = aA * pA/mA;
p1 = mA * (p1 - r1)/aA + r1;
p2 = mA * (p2 - r2)/aA + r2;
p3 = mA * (p3 - r3)/aA + r3;
} else {
pA = 0;
p1 = 0;
p2 = 0;
p3 = 0;
}
}
}
GIMP के कार्यान्वयन (here) आरजीबी रंग अंतरिक्ष का उपयोग करता है, 0 के साथ float
के रूप में 1 श्रृंखला के लिए अल्फा मान का उपयोग करता है, और R, G से float
के रूप में बी 0 से 255.
आरजीबी कार्यान्वयन शानदार रूप से विफल रहता है जब छवि में जेपीईजी कलाकृतियां होती हैं, क्योंकि उनका मतलब महत्वहीन रंग विचलन होता है, लेकिन काफी महत्वपूर्ण पूर्ण आर, जी, बी विचलन। एलएबी रंगस्थान का उपयोग करना मामले के लिए चाल करना चाहिए।
तुम सिर्फ छवि से ठोस पृष्ठभूमि को दूर करने के लिए देख रहे हैं, अल्फा एल्गोरिथ्म के लिए रंग एक इष्टतम विकल्प नहीं है। एलएबी रंगस्थान का उपयोग कर प्रत्येक पिक्सेल के लिए रंगस्थान दूरी की गणना करते समय मुझे अच्छे नतीजे मिले। गणना की गई दूरी को मूल छवि के अल्फा चैनल पर लागू किया गया था। इस और कलर से अल्फा के बीच मुख्य अंतर पिक्सल का रंग बदला नहीं जाएगा। पृष्ठभूमि निकालें केवल रंगस्थान अंतर के लिए अल्फा (अस्पष्टता) सेट करता है। अगर पृष्ठभूमि रंग अग्रभूमि छवि में नहीं होता है तो यह अच्छी तरह से काम करता है। अगर ऐसा होता है तो पृष्ठभूमि को हटाया नहीं जा सकता है, या बीएफएस एल्गोरिदम का उपयोग केवल बाहरी पिक्सेल चलने के लिए किया जाना चाहिए (कुछ ऐसा है जैसे कि जीआईएमपी में जादू वंड चयन का उपयोग करना, फिर चयन को हटा देना)। अगर अग्रभूमि छवि पृष्ठभूमि रंग के समान रंग में दोनों छेद और पिक्सल है
पृष्ठभूमि हटाया नहीं जा सकता। ऐसी छवियों को कुछ मैन्युअल प्रसंस्करण की आवश्यकता होती है।
संबंधित प्रश्न: http://stackoverflow.com/questions/9282714/how-to-change-the-alpha-of-a-pixel-without-changing-the-resulting-color –
@MarkRansom मुझे पता है कि सवाल यह है कि आपने एक लिंक पोस्ट किया है, जिसने मुझसे पूछा था कि सवाल मुझे था! :) और भले ही आपका फॉर्मूला इस गिंप की सुविधा के प्रभाव को प्राप्त कर सके, फिर भी रहस्य तब भी है जब मैंने गिंप के स्रोतों में जो देखा, उसकी जटिलता आपके सूत्र के मुकाबले ज्यादा है। –
@MarkRansom निरंतर: लेकिन आपका दृष्टिकोण जिम्प की तुलना में अधिक लचीला प्रतीत होता है, समीकरणों की एक पुनर्लेखित प्रणाली के समाधान के साथ, कोई एक रंग की पृष्ठभूमि से एक छवि को "काट" सकता है और इसे किसी अन्य रंग की पृष्ठभूमि पर रख सकता है , और छवि अभी भी वही दिखाई देगी। तो मुझे लगता है कि इस सवाल में अब कोई और बात नहीं है, इसलिए यदि कोई भी बुरा नहीं मानता है तो मैं इस प्रश्न को हटाने के लिए पंजीकृत करूँगा। –