增加颜色对比中的相对值对比方法。

This commit is contained in:
徐涛 2025-01-14 10:51:31 +08:00
parent 60d1f82e09
commit b7a5c4a109
6 changed files with 208 additions and 0 deletions

View File

@ -35,4 +35,38 @@ impl ColorDifference for Cam16Jch<f32> {
}, },
} }
} }
fn difference_relative(&self, other: &Self) -> Self::Difference {
let hue = if self.hue.into_positive_degrees() == 0.0 {
0.0
} else {
(other.hue.into_positive_degrees() - self.hue.into_positive_degrees())
/ (1.0 - self.hue.into_positive_degrees())
};
let chroma = if self.chroma == 0.0 {
0.0
} else {
(other.chroma - self.chroma) / self.chroma
};
let lightness = if self.lightness == 0.0 {
0.0
} else {
(other.lightness - self.lightness) / self.lightness
};
HctDiffference {
hue: Differ {
delta: other.hue.into_positive_degrees() - self.hue.into_positive_degrees(),
percent: hue,
},
chroma: Differ {
delta: other.chroma - self.chroma,
percent: chroma,
},
lightness: Differ {
delta: other.lightness - self.lightness,
percent: lightness,
},
}
}
} }

View File

@ -35,4 +35,38 @@ impl ColorDifference for Hsl {
}, },
} }
} }
fn difference_relative(&self, other: &Self) -> Self::Difference {
let hue = if self.hue.into_positive_degrees() == 0.0 {
0.0
} else {
(other.hue.into_positive_degrees() - self.hue.into_positive_degrees())
/ (1.0 - self.hue.into_positive_degrees())
};
let saturation = if self.saturation == 0.0 {
0.0
} else {
(other.saturation - self.saturation) / (1.0 - self.saturation)
};
let lightness = if self.lightness == 0.0 {
0.0
} else {
(other.lightness - self.lightness) / (1.0 - self.lightness)
};
HSLDifference {
hue: Differ {
delta: other.hue.into_positive_degrees() - self.hue.into_positive_degrees(),
percent: hue,
},
saturation: Differ {
delta: other.saturation - self.saturation,
percent: saturation,
},
lightness: Differ {
delta: other.lightness - self.lightness,
percent: lightness,
},
}
}
} }

View File

@ -17,4 +17,5 @@ pub trait ColorDifference {
type Difference; type Difference;
fn difference(&self, other: &Self) -> Self::Difference; fn difference(&self, other: &Self) -> Self::Difference;
fn difference_relative(&self, other: &Self) -> Self::Difference;
} }

View File

@ -35,4 +35,38 @@ impl ColorDifference for Oklch {
}, },
} }
} }
fn difference_relative(&self, other: &Self) -> Self::Difference {
let hue = if self.hue.into_positive_degrees() == 0.0 {
0.0
} else {
(other.hue.into_positive_degrees() - self.hue.into_positive_degrees())
/ (1.0 - self.hue.into_positive_degrees())
};
let chroma = if self.chroma == 0.0 {
0.0
} else {
(other.chroma - self.chroma) / self.chroma
};
let lightness = if self.l == 0.0 {
0.0
} else {
(other.l - self.l) / (1.0 - self.l)
};
OklchDifference {
hue: Differ {
delta: other.hue.into_positive_degrees() - self.hue.into_positive_degrees(),
percent: hue,
},
chroma: Differ {
delta: other.chroma - self.chroma,
percent: chroma,
},
lightness: Differ {
delta: other.l - self.l,
percent: lightness,
},
}
}
} }

View File

@ -35,4 +35,37 @@ impl ColorDifference for Srgb {
}, },
} }
} }
fn difference_relative(&self, other: &Self) -> Self::Difference {
let r = if self.red == 0.0 {
0.0
} else {
(other.red - self.red) / (1.0 - self.red)
};
let g = if self.green == 0.0 {
0.0
} else {
(other.green - self.green) / (1.0 - self.green)
};
let b = if self.blue == 0.0 {
0.0
} else {
(other.blue - self.blue) / (1.0 - self.blue)
};
RGBDifference {
r: Differ {
delta: other.red - self.red,
percent: r,
},
g: Differ {
delta: other.green - self.green,
percent: g,
},
b: Differ {
delta: other.blue - self.blue,
percent: b,
},
}
}
} }

View File

@ -440,6 +440,20 @@ pub fn differ_in_rgb(
Ok(srgb.difference(&other_srgb)) Ok(srgb.difference(&other_srgb))
} }
#[wasm_bindgen]
pub fn relative_differ_in_rgb(
color: &str,
other: &str,
) -> Result<color_differ::rgb::RGBDifference, errors::ColorError> {
let srgb = Srgb::from_str(color)
.map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))?
.into_format::<f32>();
let other_srgb = Srgb::from_str(other)
.map_err(|_| errors::ColorError::UnrecogniazedRGB(other.to_string()))?
.into_format::<f32>();
Ok(srgb.difference_relative(&other_srgb))
}
#[wasm_bindgen] #[wasm_bindgen]
pub fn differ_in_hsl( pub fn differ_in_hsl(
color: &str, color: &str,
@ -458,6 +472,24 @@ pub fn differ_in_hsl(
Ok(hsl.difference(&other_hsl)) Ok(hsl.difference(&other_hsl))
} }
#[wasm_bindgen]
pub fn relative_differ_in_hsl(
color: &str,
other: &str,
) -> Result<color_differ::hsl::HSLDifference, errors::ColorError> {
let hsl = Hsl::from_color(
Srgb::from_str(color)
.map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))?
.into_format::<f32>(),
);
let other_hsl = Hsl::from_color(
Srgb::from_str(other)
.map_err(|_| errors::ColorError::UnrecogniazedRGB(other.to_string()))?
.into_format::<f32>(),
);
Ok(hsl.difference_relative(&other_hsl))
}
#[wasm_bindgen] #[wasm_bindgen]
pub fn differ_in_hct( pub fn differ_in_hct(
color: &str, color: &str,
@ -480,6 +512,28 @@ pub fn differ_in_hct(
Ok(hct.difference(&other_hct)) Ok(hct.difference(&other_hct))
} }
#[wasm_bindgen]
pub fn relative_differ_in_hct(
color: &str,
other: &str,
) -> Result<color_differ::cam16jch::HctDiffference, errors::ColorError> {
let hct = Cam16Jch::from_xyz(
Srgb::from_str(color)
.map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))?
.into_format::<f32>()
.into_color(),
Parameters::default_static_wp(40.0),
);
let other_hct = Cam16Jch::from_xyz(
Srgb::from_str(other)
.map_err(|_| errors::ColorError::UnrecogniazedRGB(other.to_string()))?
.into_format::<f32>()
.into_color(),
Parameters::default_static_wp(40.0),
);
Ok(hct.difference_relative(&other_hct))
}
#[wasm_bindgen] #[wasm_bindgen]
pub fn differ_in_oklch( pub fn differ_in_oklch(
color: &str, color: &str,
@ -498,6 +552,24 @@ pub fn differ_in_oklch(
Ok(oklch.difference(&other_oklch)) Ok(oklch.difference(&other_oklch))
} }
#[wasm_bindgen]
pub fn relative_differ_in_oklch(
color: &str,
other: &str,
) -> Result<color_differ::oklch::OklchDifference, errors::ColorError> {
let oklch = Oklch::from_color(
Srgb::from_str(color)
.map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))?
.into_format::<f32>(),
);
let other_oklch = Oklch::from_color(
Srgb::from_str(other)
.map_err(|_| errors::ColorError::UnrecogniazedRGB(other.to_string()))?
.into_format::<f32>(),
);
Ok(oklch.difference_relative(&other_oklch))
}
#[wasm_bindgen] #[wasm_bindgen]
pub fn tint_scale( pub fn tint_scale(
basic_color: &str, basic_color: &str,