আরবিজিকে আর জিবিএতে সাদা রূপে রূপান্তর করুন


196

আমার একটি হেক্স রঙ রয়েছে, যেমন #F4F8FB(বা rgb(244, 248, 251)) যা আমি একটি স্বচ্ছ-যতটা সম্ভব আরজিবা রঙে রূপান্তর করতে চাই (যখন সাদা রঙের উপরে প্রদর্শিত হয়)। ধারণা তৈরী কর? আমি কীভাবে এটি করতে হয় তার জন্য একটি অ্যালগরিদম বা কমপক্ষে একটি অ্যালগরিদমের ধারণা খুঁজছি।

উদাহরণ স্বরূপ:

rgb( 128, 128, 255 ) --> rgba(   0,   0, 255,  .5 )
rgb( 152, 177, 202 ) --> rgba(  50, 100, 150,  .5 ) // can be better(lower alpha)

ধারনা?


গুফার উত্তরের ভিত্তিতে এফওয়াইআই সমাধান:

function RGBtoRGBA(r, g, b){
    if((g == null) && (typeof r === 'string')){
        var hex = r.replace(/^\s*#|\s*$/g, '');
        if(hex.length === 3){
            hex = hex.replace(/(.)/g, '$1$1');
        }
        r = parseInt(hex.substr(0, 2), 16);
        g = parseInt(hex.substr(2, 2), 16);
        b = parseInt(hex.substr(4, 2), 16);
    }

    var min, a = (255 - (min = Math.min(r, g, b))) / 255;

    return {
        r    : r = 0|(r - min) / a,
        g    : g = 0|(g - min) / a,
        b    : b = 0|(b - min) / a,
        a    : a = (0|1000*a)/1000,
        rgba : 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')'
    };
}

RGBtoRGBA(204, 153, 102) == RGBtoRGBA('#CC9966') == RGBtoRGBA('C96') == 
    {
       r    : 170,
       g    : 85 ,
       b    : 0  ,
       a    : 0.6,
       rgba : 'rgba(170, 85, 0, 0.6)' 
    }

Interseting! আপনি এখনও এটি পুরোপুরি স্বচ্ছ নয়, সঠিকভাবে দৃশ্যমান হতে চান?
মিচিফ

6
মজার প্রশ্ন! সেখানে একটি সঠিক বিপরীত প্রশ্ন stackoverflow.com/questions/2049230/convert-rgba-color-to-rgb , এটা সাহায্য করতে পারে
apscience

@ মিছরিফ - হ্যাঁ, আমি সাদা রঙের উপরে প্রদর্শিত হলে রঙটি একই রকম দেখতে চাই, তবে যতটা সম্ভব স্বচ্ছ হোক।
মার্ক কাহন

1
দুর্দান্ত প্রশ্ন, আমি কীভাবে এটি করব তা সবসময়ই ভাবছিলাম, তবে সাধারণত এ থেকে দূরে থাকি;) +1
ডমিনিক কে

1
@ e100 - নির্দিষ্ট প্রশ্ন যে এই আলোড়ন সৃষ্টি ছিল stackoverflow.com/questions/6658350/... । মূলত আমি চাইচ্ছিলাম যে সমস্ত কিছুগুলির উপরে ছায়া উপাদান স্থাপন করে ক্লিক-থ্রোকে ব্লক না করে ব্যাকগ্রাউন্ড-রঙযুক্ত উপাদানগুলির শীর্ষে সিএসএসের ছায়াগুলি ওভারলে করতে সক্ষম হতে হবে। আমি এটিও কিছু সময়ের জন্য করতে চেয়েছিলাম যাতে আমি এলোমেলো জিনিসগুলি যেমন: jsfiddle.net/qwySW/2 করতে পারি । প্লাস আমি কেবল এটি একটি আকর্ষণীয় প্রশ্ন বলে মনে করেছি :)
মার্ক কাহন

উত্তর:


185

সর্বনিম্ন রঙের উপাদানটি নিন এবং এটিকে একটি আলফা মানতে রূপান্তর করুন। তারপরে নিম্নতমটি বিয়োগ করে এবং আলফা মান দ্বারা ভাগ করে রঙের উপাদানগুলি স্কেল করুন।

উদাহরণ:

152 converts to an alpha value of (255 - 152) / 255 ~ 0.404

152 scales using (152 - 152) / 0.404 = 0
177 scales using (177 - 152) / 0.404 ~ 62
202 scales using (202 - 152) / 0.404 ~ 123

সুতরাং, rgb(152, 177, 202)হিসাবে প্রদর্শন করেrgba(0, 62, 123, .404)

আমি ফটোশপে যাচাই করেছি যে রঙগুলি আসলে পুরোপুরি মেলে।


1
ধন্যবাদ! আমি অনুরূপ কিছু করছিলাম (যেমন: পেতে .404) তবে বেশিরভাগ সংখ্যা কাজ করতে পারা যায় নি।
মার্ক কাহন

3
এফওয়াইআই, আপনার প্রশ্নের উত্তরের ভিত্তিতে চূড়ান্ত সমাধান পোস্ট করেছে
মার্ক ক্যান

2
@templatetypedef: আলফা-তে Te সর্বনিম্ন উপাদান রূপান্তর ব্যাপ্তি থেকে স্কেলিং হয় 0..255থেকে 0..1, এবং ইনভার্টারিং। ব্যবহার 1.0 - 152 / 255করেও কাজ হবে। রূপান্তর রঙ উপাদান কেবল থেকে স্কেলিং করা হয় n..255থেকে 0..255যেখানে nসর্বনিম্ন উপাদান।
গুফা

1
@ ক্রিসটফ: নীতিটি একই হবে তবে আরও জটিল। কেবলমাত্র আলফা গণনা করার জন্য সর্বনিম্ন উপাদানটি ব্যবহার না করে আপনি প্রতিটি উপাদানটির জন্য সর্বনিম্ন সম্ভাব্য আলফা গণনা করবেন (যেমন উপাদানটির মান হিসাবে 0 বা 255 ব্যবহার করার সময় সঠিক বর্ণটি পেতে আলফার মানটি ব্যবহার করতে হবে), তবে সর্বোচ্চটি ব্যবহার করুন এই আলফা মানগুলির। সেখান থেকে আপনি সেই আলফা মান সহ প্রতিটি উপাদানগুলির জন্য সঠিক রঙ পেতে কোন রঙের মানটি গণনা করতে পারেন। নোট করুন যে কিছু রঙ সমন্বয় (উদাহরণস্বরূপ কালো পটভূমিতে সাদা) ব্যবহার করার জন্য সর্বনিম্ন সম্ভব আলফা মান হিসাবে 1.0 প্রদান করবে।
গুফা

2
আমি একটি ছোট্ট ফিডল লিখেছিলাম যা এই সমাধানটি কার্যকর করে। লিঙ্কটি এখানে। jsfiddle.net/wb5fwLoc/1 । হয়ত আপনারা কেউ এটি ব্যবহার করতে পারেন। এটি কেবলমাত্র একটি তাত্ক্ষণিক, বাগ-মুক্ত স্ক্রিপ্ট নয় .. এটি চারপাশের খেলার পক্ষে যথেষ্ট ভাল হওয়া উচিত।
chsymann

23

R, g এবং b এর ইনপুট মান এবং r ', g', b 'এবং একটি' আউটপুট মান হতে হবে, সমস্ত মাপা (বর্তমানে এটি গণিতকে সুন্দর করে তোলে) 1 এবং 0 এর মধ্যে by ওভারলেয়িং রঙের সূত্র:

r = a' * r' + 1 - a'
g = a' * g' + 1 - a'
b = a' * b' + 1 - a'

1 - একটি 'পদগুলি পটভূমির অবদানকে উপস্থাপন করে এবং অন্যান্য শর্তাগুলি অগ্রভাগের প্রতিনিধিত্ব করে। কিছু বীজগণিত করুন:

r = a' * (r' - 1) + 1
r - 1 = a' * (r' - 1)
(r - 1) / (r' - 1) = a'
(r' - 1) / (r - 1) = 1 / a'
r' - 1 = (r - 1) / a'
r' = (r - 1) / a' + 1

স্বজ্ঞাতভাবে, মনে হচ্ছে ন্যূনতম রঙের মানটি সমস্যার সীমাবদ্ধ ফ্যাক্টর হবে, তাই এটি এমকে আবদ্ধ করুন:

m = min(r, g, b)

আমরা স্বচ্ছতা বাড়িয়ে তুলতে চাইলে সংশ্লিষ্ট আউটপুট মান, মি 'কে শূন্যতে সেট করুন:

0 = (m - 1) / a' + 1
-1 = (m - 1) / a'
-a' = m - 1
a' = 1 - m

সুতরাং, জাভাস্ক্রিপ্টে (1 থেকে 255 পথে অনুবাদ করা):

function rgba(r, g, b) {
    var a = 1 - Math.min(r, Math.min(g, b)) / 255;
    return [255 + (r - 255) / a, 255 + (g - 255) / a, 255 + (b - 255) / a, a];
}

নোট করুন যে আমি ধরে নিচ্ছি যে এখানে একটি 'ধোঁয়াটে। এটিকে স্বচ্ছতায় পরিবর্তন করা তুচ্ছ - কেবল একটি 'এর সূত্র থেকে "1 -" সরান। কিছু খেয়াল করার মতো বিষয় এটি সঠিক ফলাফল বলে মনে হচ্ছে না - এটি বলেছে যে উপরে বর্ণিত উদাহরণটির জন্য অস্বচ্ছতা 0.498 ছিল (128, 128, 255)। তবে এটি অত্যন্ত নিকটে close


আপনি আপনার সমীকরণ বৃদ্ধি 255 বিতরণ তাহলে আপনি সঠিক ফলাফল পেতে -[255 * (r/255 - 1) / a + 1 * 255, ...] == [(255*r/255 - 255 * 1) / a + 255, ...] == [(r - 255) / a + 255, ...]
gereeter

6

আমি আরজিবি <-> এইচএসএল রূপান্তরটি সন্ধান করব। অর্থাত আলোকিততা == সাদা পরিমাণ == স্বচ্ছতার পরিমাণ।

আপনার উদাহরণস্বরূপ rgb( 128, 128, 255 ), আমাদের আরজিবি মানগুলি 0প্রথমে সর্বাধিক পরিমাণে স্থানান্তরিত করা প্রয়োজন , অর্থাত্ rgb( 0, 0, 128 )- এটি আমাদের রঙ যতটা সম্ভব সাদা হবে। এবং তার পরে, আলোকসজ্জার সূত্র ব্যবহার করে, আমরা আসল রঙ পেতে আমাদের গা dark় রঙে যে পরিমাণ সাদা যোগ করতে হবে তা গণনা করি - এটি আমাদের আলফা হবে:

L = (MAX(R,G,B) + MIN(R,G,B))/2
L1 = (255 + 128) / 2 = 191.5
L2 = (128 + 0) /2 = 64
A = (191,5 - 64) / 255 = 0,5;

আশা করি তা বোধগম্য হয়। :)


6

আপনারা SASS / SCSS ব্যবহার করছেন তাদের জন্য, আমি একটি ছোট এসসিএসএস ফাংশন লিখেছি যাতে আপনি @ গুফা দ্বারা বর্ণিত অ্যালগরিদম সহজেই ব্যবহার করতে পারেন

@function transparentize-on-white($color)
{
    $red: red($color);
    $green: green($color);
    $blue: blue($color);
    $lowestColorComponent: min($red, $green, $blue);
    $alpha: (255 - $lowestColorComponent) / 255;

    @return rgba(
        ($red - $lowestColorComponent) / $alpha,
        ($green - $lowestColorComponent) / $alpha,
        ($blue - $lowestColorComponent) / $alpha,
        $alpha
    );
}

3

আমি কেবল অ্যালগরিদমের জন্য একটি ধারণা বর্ণনা করছি, কোনও সম্পূর্ণ সমাধান নেই:

মূলত, আপনি তিনটি সংখ্যার আছে x, y, zএবং আপনি তিনটি নতুন সংখ্যার জন্য খুঁজছি হয় x', y', z'এবং একটি গুণক aসীমার মধ্যে [0,1] এই ধরনের যে:

x = a + (1 - a) x'
y = a + (1 - a) y'
z = a + (1 - a) z'

এটি এমন এককগুলিতে লেখা যেখানে চ্যানেলগুলি [0,1] এর মধ্যেও মান গ্রহণ করে। 8 বিট পৃথক মানগুলিতে, এটি এরকম কিছু হবে:

x = 255 a + (1 - a) x'
y = 255 a + (1 - a) y'
z = 255 a + (1 - a) z'

তদতিরিক্ত, আপনি সর্বাধিক সম্ভাব্য মান চান a। আপনি সমাধান করতে পারেন:

a  = (x - x')/(255 - x')          x' = (x - 255 a)/(1 - a)

ইত্যাদির প্রকৃত মূল্যবোধগুলিতে এটির অসীম অনেকগুলি সমাধান রয়েছে, কেবল কোনও আসল সংখ্যায় প্লাগ ইন করুন a, তবে সমস্যাটি এমন একটি সংখ্যা খুঁজে পাওয়া যায় যার জন্য বিবেচনার ত্রুটিটি সর্বনিম্ন।


0

এটি করা উচিত:

let x = min(r,g,b)
a = 1 - x/255                    # Correction 1
r,g,b = ( (r,g,b) - x ) / a      # Correction 2

আমি আসলে ঠিক লক্ষ্য করেছি যে আমার আলফা ক্যালকের একটি ত্রুটি ছিল (এখনই স্থির)। সুতরাং এটির সাথেও কিছু করার ছিল।
ট্রুথিলিটি

আপনার yএবং দ্বারা প্রবর্তিত সমস্যা এখনও আছে (y-x)255 / (y-x)ভুল থেকে বৃহত্তম সংখ্যা বাধ্য করে 255, ফলে আপনি সর্বদা একটি একক দিয়ে শেষ চাই 0, একটি একক 255এবং তারপর অন্য একটি নম্বর: 0, 22, 255, 255, 0, 55, ইত্যাদি ...
মার্ক কানের

আমি দেখতে পাচ্ছি, তাই এটি গাer় রঙের জন্য অনুমতি দেয় না ... আমার কেবল এটি করা উচিত /aএবং তারপরে এটি সঠিক উত্তরটির সাথে মেলে।
ট্রুথিলিটি

-1

উপরের উত্তরটি কম রঙের উপাদান সহ আমার পক্ষে কাজ করে না। উদাহরণস্বরূপ, যদি রঙটি 80000 হয় তবে এটি সঠিক আলফা গণনা করে না। প্রযুক্তিগতভাবে এটি আলফা 0.5 দিয়ে # ff0000 করা উচিত। এটি সমাধানের জন্য আপনাকে আরজিবি -> এইচএসএল -> আরজিবিএ রূপান্তর ব্যবহার করতে হবে। সঠিক মানগুলি পেতে এটি ছদ্ম কোড:

//Convert RGB to HSL
hsl = new HSL(rgb)

//Use lightness as alpha
alpha = hsl.Lightness

//For #80000 lightness is 0.5, so we have to take this into account.
//Lightness more than 0.5 converts to alpha 1 and below is a linear ratio
if (alpha > 0.5)
{
    alpha = 1;
}
else
{
    alpha = alpha / 0.5;
    //We need to drop the lightness of the color to 0.5 to get the actual color
    //that needs to display. Alpha blending will take care of that.
    hsl.Lightness = 0.5;
}

newRgb = hsl.convertToRgb()

"newRgb" এ নতুন সামঞ্জস্য করা রঙের মান ধারণ করবে এবং স্বচ্ছতা নিয়ন্ত্রণ করতে "আলফা" পরিবর্তনশীল ব্যবহার করবে।


#800000এবং rgba( 255, 0, 0, .5 )একই রঙের কাছাকাছি কোথাও নেই। প্রথমটি গা dark় লাল, দ্বিতীয় সালমন-ইশ হবে। কালো রঙের উপরে প্রদর্শন না করা না হলে আমি মনে করি তারা একই হবে।
মার্ক কাহন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.