Saya memiliki warna hex, misalnya #F4F8FB
(atau rgb(244, 248, 251)
) yang ingin saya ubah menjadi warna rgba yang setransparan mungkin (bila ditampilkan di atas putih). Masuk akal? Saya sedang mencari suatu algoritma, atau setidaknya ide dari suatu algoritma untuk bagaimana melakukannya.
Sebagai contoh:
rgb( 128, 128, 255 ) --> rgba( 0, 0, 255, .5 )
rgb( 152, 177, 202 ) --> rgba( 50, 100, 150, .5 ) // can be better(lower alpha)
Ide ide?
Solusi FYI berdasarkan jawaban Guffa:
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)'
}
javascript
colors
css
rgba
Mark Kahn
sumber
sumber
Jawaban:
Ambil komponen warna terendah, dan ubah itu menjadi nilai alpha. Kemudian skala komponen warna dengan mengurangi yang terendah, dan membaginya dengan nilai alpha.
Contoh:
Jadi,
rgb(152, 177, 202)
tampilkan sebagairgba(0, 62, 123, .404)
.Saya telah memverifikasi di Photoshop bahwa warnanya benar-benar cocok dengan sempurna.
sumber
.404
) tetapi tidak bisa mendapatkan angka untuk berhasil.0..255
ke0..1
, dan pembalikan. Menggunakan1.0 - 152 / 255
juga akan berhasil. Konversi komponen warna hanyalah penskalaan darin..255
ke0..255
tempatn
komponen terendah.Biarkan r, g, dan b menjadi nilai input dan r ', g', b ', dan a' menjadi nilai output, semua diskalakan (untuk saat ini, karena membuat matematika lebih cantik) antara 1 dan 0. Kemudian, dengan rumus untuk overlay warna:
Istilah 1 - a 'mewakili kontribusi latar belakang, dan istilah lainnya mewakili latar depan. Lakukan beberapa aljabar:
Secara intuitif, tampaknya nilai warna minimum akan menjadi faktor pembatas dalam masalah, jadi ikat ini ke m:
Tetapkan nilai output yang sesuai, m ', ke nol, karena kami ingin memaksimalkan transparansi:
Jadi, dalam javascript (menerjemahkan dari 1 hingga 255 sepanjang jalan):
Perhatikan bahwa saya berasumsi bahwa 'opacity di sini. Sangat mudah untuk mengubahnya menjadi transparansi - cukup hapus "1 -" dari rumus untuk a '. Yang perlu diperhatikan adalah bahwa ini tampaknya tidak menghasilkan hasil yang tepat - dikatakan bahwa opacity adalah 0,498 untuk contoh yang Anda berikan di atas (128, 128, 255). Namun, ini sangat dekat.
sumber
[255 * (r/255 - 1) / a + 1 * 255, ...] == [(255*r/255 - 255 * 1) / a + 255, ...] == [(r - 255) / a + 255, ...]
Saya akan melihat konversi RGB <-> HSL. Yaitu luminositas == jumlah putih == jumlah transparansi.
Sebagai contoh Anda
rgb( 128, 128, 255 )
, kami perlu menggeser nilai RGB ke0
pertama dengan jumlah maksimum, yaitu kergb( 0, 0, 128 )
- yang akan menjadi warna kami dengan sesedikit mungkin putih. Dan setelah itu, menggunakan formula untuk luminance, kita menghitung jumlah putih yang kita perlu tambahkan ke warna gelap kita untuk mendapatkan warna asli - yang akan menjadi alpha kita:Harapan itu masuk akal. :)
sumber
Bagi Anda yang menggunakan SASS / SCSS, saya telah menulis fungsi SCSS kecil sehingga Anda dapat dengan mudah menggunakan algoritma yang dijelaskan oleh @Guffa
sumber
Saya hanya menjelaskan ide untuk algoritma, tidak ada solusi lengkap:
Pada dasarnya, Anda memiliki tiga angka
x
,y
,z
dan Anda mencari tiga angka barux'
,y'
,z'
dan penggandaa
dalam rentang [0,1] sehingga:Ini ditulis dalam satuan di mana saluran juga mengambil nilai dalam kisaran [0,1]. Dalam nilai diskrit 8bit, itu akan menjadi seperti ini:
Selain itu, Anda menginginkan nilai sebesar mungkin
a
. Anda dapat memecahkan:Dll. Dalam nilai riil ini memiliki banyak solusi tak terbatas, cukup tancapkan bilangan real mana pun
a
, tetapi masalahnya adalah menemukan nomor yang kesalahan diskritasinya minimal.sumber
Ini harus dilakukan:
sumber
y
dan(y-x)
. The255 / (y-x)
benar memaksa jumlah terbesar untuk255
, sehingga Anda akan selalu berakhir dengan satu0
, tunggal255
dan kemudian nomor lain:0, 22, 255
,255, 0, 55
, dll .../a
dan kemudian cocok dengan jawaban yang benar.Jawaban teratas tidak berfungsi untuk saya dengan komponen warna rendah. Misalnya tidak menghitung alpha yang benar jika warnanya # 80000. Secara teknis itu harus membuatnya menjadi # ff0000 dengan alpha 0,5. Untuk mengatasi ini, Anda perlu menggunakan RGB -> HSL -> konversi RGBA. Ini adalah kode semu untuk mendapatkan nilai yang benar:
"newRgb" akan berisi nilai warna yang disesuaikan baru dan menggunakan variabel "alpha" untuk mengontrol transparansi.
sumber
#800000
danrgba( 255, 0, 0, .5 )
jauh dari warna yang sama. Yang pertama adalah merah tua, salmon-ish kedua. Kecuali menampilkan lebih dari hitam, maka saya pikir mereka akan sama.