Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mismatched colors comparing to Material Theme Builder #5

Closed
PoSayDone opened this issue Feb 1, 2024 · 20 comments
Closed

Mismatched colors comparing to Material Theme Builder #5

PoSayDone opened this issue Feb 1, 2024 · 20 comments
Assignees
Labels
bug Something isn't working

Comments

@PoSayDone
Copy link

For some reason, colors provided by this library differs from colors provided by material theme builder.
for me, the colors don't match in many pictures after the update(
(Also --show-colors order is random for some reason)

Examples are taken with https://github.com/InioX/matugen, but bare library with the example provided on the main page are giving the same results.

Example one material theme builder:

image

matugen:

image

source:
https://i.imgur.com/AoaBp86.jpeg

Example two material theme builder:

image

matugen:

image

soruce:
https://i.imgur.com/u7OjTQz.jpeg

@PoSayDone
Copy link
Author

Sorry for being dumbass, I've not resized image before generating theme and https://github.com/InioX/matugen is having the same issue.

@PoSayDone
Copy link
Author

Well, I tried a few other images, got colors slightly different from Material Theme Builder, but nothing critical. But I found an image that gives completely wrong color, even changing its size to 128x128.
I tried changing filter types, other filters gave a color more similar to green (Lanczos3 gave a color closer to cyan), but after trying all the filters I couldn't find one that would give the same/maximum close to what Material Theme Builder generates.

(all colors are for dark pallete)

image:
https://i.imgur.com/VODdkHM.png

Lanczos3 primary color:
image
#8ad6b7

Gaussian primary color:
image
#fdb0d4

Material Theme Builder color:
image
#b1d18a

@PoSayDone PoSayDone reopened this Feb 1, 2024
@Aiving
Copy link
Owner

Aiving commented Feb 1, 2024

To be honest, I wouldn't trust the results of Material Theme Builder too much. They are still correct, but most likely can only be obtained on the TypeScript version of material-color-utilities (which is considered somewhat outdated in the community because it uses the previous palette generation algorithm). I'll check the results of the Java version, since that's what Android itself uses.

@Aiving
Copy link
Owner

Aiving commented Feb 1, 2024

Well, it looks like getting the color from the image really doesn't work right.
Results of the Java version of the library: #75c133
Material-colors results: #ffb2ba
In both cases, the image was not resized in any way.
I will try to fix it soon.

@PoSayDone
Copy link
Author

PoSayDone commented Feb 1, 2024

To be honest, I wouldn't trust the results of Material Theme Builder too much. They are still correct, but most likely can only be obtained on the TypeScript version of material-color-utilities (which is considered somewhat outdated in the community because it uses the previous palette generation algorithm). I'll check the results of the Java version, since that's what Android itself uses.

Yeah, I totally understand that, but pink theme from green image is something extraordinary)

P.S. there are two versions of Material Theme Builder.

more updated one: https://material-foundation.github.io/material-theme-builder/
the old one: https://m3.material.io/theme-builder

Well, it looks like getting the color from the image really doesn't work right. Results of the Java version of the library: #75c133 Material-colors results: #ffb2ba In both cases, the image was not resized in any way. I will try to fix it soon.

Thank you for such a quick response. I'll look forward to it!

@Aiving
Copy link
Owner

Aiving commented Feb 1, 2024

Well, it seems the issue with that image is now resolved (6713236). However, I'm not sure, since the same image but in a resolution of 1920x1080 gave out a different color (something like purple). But the resize of the original image to 128x128 with filterType::Gaussian showed approximately the same color as the original (i.e. green). Sorry for the tautology.

@PoSayDone
Copy link
Author

Well, it seems the issue with that image is now resolved (6713236). However, I'm not sure, since the same image but in a resolution of 1920x1080 gave out a different color (something like purple). But the resize of the original image to 128x128 with filterType::Gaussian showed approximately the same color as the original (i.e. green). Sorry for the tautology.

Yeah, seems to be fixed for me!

So the java library doesn't give purple color at 1920x1080?

@Aiving
Copy link
Owner

Aiving commented Feb 2, 2024

So the java library doesn't give purple color at 1920x1080?

No, it still gives out green

@Aiving
Copy link
Owner

Aiving commented Feb 2, 2024

Well, I do not know how to fix it. Java java.awt.image.BufferedImage and Rust image::io::Reader give different pixel arrays when reading the same file. Of the 22,500 pixels, 358 differ. It seems to be a little, but as a result, the libraries give completely different results.

@Aiving Aiving self-assigned this Feb 2, 2024
@Aiving Aiving added the bug Something isn't working label Feb 2, 2024
@PoSayDone
Copy link
Author

PoSayDone commented Feb 2, 2024

Well, I do not know how to fix it. Java java.awt.image.BufferedImage and Rust image::io::Reader give different pixel arrays when reading the same file. Of the 22,500 pixels, 358 differ. It seems to be a little, but as a result, the libraries give completely different results.

Have you tried using a Java resulted pixel array in your library or vice versa?

@PoSayDone
Copy link
Author

PoSayDone commented Feb 2, 2024

I've tried to write java's pixel array to txt file and proceed it with your library.
(I've also resized image to 1920x1080)

import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.*;
import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        try {
            BufferedImage image = ImageIO.read(new File("/home/posaydone/Pictures/wallpapers/wallhaven-m3r6ry.png"));
            int[] pixels = imageToPixels(image);
            try (PrintWriter out = new PrintWriter("/home/posaydone/pixels.txt")) {
                out.println(Arrays.toString(pixels));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    public static int[] imageToPixels(BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        return image.getRGB(0, 0, 1920, 1080, null, 0, width);
    }

}

then I've tried to import this pixel array to rust:

fn main() {
    let file_path = "/home/posaydone/pixels.txt";
    let mut file = File::open(file_path).expect("Failed to open file");

    let mut content = String::new();
    file.read_to_string(&mut content).expect("Failed to read file");

    let array: Vec<i32> = serde_json::from_str(&content).expect("Failed to parse JSON");
    let pixels: Vec<Argb> = get_argb_array(array);

    let theme = theme_from_source_color(source_color_from_image(&pixels), Default::default()).schemes.dark;
    ...
}

fn get_argb_array(input_array: Vec<i32>) -> Vec<Argb> {
    let mut argb_array = Vec::new();

    for &value in input_array.iter() {
        // Extract individual components using bit manipulation and masking
        let alpha = ((value >> 24) & 0xFF) as u8;
        let red = ((value >> 16) & 0xFF) as u8;
        let green = ((value >> 8) & 0xFF) as u8;
        let blue = (value & 0xFF) as u8;

        // Append the components to the output array
        argb_array.push([alpha, red, green, blue]);
    }

    argb_array
}

And for discussed image I get #96cdf8 primary color (dark scheme).

I've also tried to use another image, and for https://i.imgur.com/AoaBp86.jpeg I get #ffb77d, as expected.

@Aiving
Copy link
Owner

Aiving commented Feb 2, 2024

It seems that the problem was the lack of an LCG random number generator. It is used in the Java version to fill in clusterIndicies (random.nextInt(clusterCount)), while in my code it was filled using index % cluster_count. It seems that after a8c4045 the problem should be solved.

@Aiving
Copy link
Owner

Aiving commented Feb 2, 2024

Finally closes after 511b23a (now the Java and Rust libraries output the same colors)

@PoSayDone
Copy link
Author

Hey, I think I've got a regression :(

code
use material_colors::{
    image::{FilterType, ImageReader},
    theme::ThemeBuilder,
};

use serde::{Deserialize, Serialize};
use serde_json;

#[derive(Serialize, Deserialize)]
struct Colors {
    primary: String,
    on_primary: String,
    background: String,
    on_background: String,
    primary_container: String,
}

fn main() {
    let args: Vec<String> = std::env::args().collect();
    if args.len() < 2 {
        println!("Please provide the path to the image as a command line argument.");
    }

    let path = &args[1];

    let mut data = ImageReader::open(path)
        .expect("failed to open image");

    data.resize(128, 128, FilterType::Lanczos3);


    let theme = ThemeBuilder::with_source(ImageReader::extract_color(&data)).build().schemes.dark;

    let colors = Colors {
        primary: format!("{}", (&theme.primary)),
        on_primary: format!("{}", (&theme.on_background)),
        background: format!("{}", (&theme.background)),
        on_background: format!("{}", (&theme.on_background)),
        primary_container: format!("{}", (&theme.primary_container)),
    };

    let json_string = serde_json::to_string(&colors).unwrap();
    println!("{}", json_string);
}
image

berserk-aj

material theme builder dark primary: #ffb4a9
material colors dark primary: #f9ba72

some other images with the wrong colors:

images

Protea

wallhaven-qzlzkr

@Aiving
Copy link
Owner

Aiving commented May 3, 2024

It seems to me that the fact is that the Material Theme Builder does not change the size of the image in any way. Are the colors still incorrect after deleting a line that uses the resize function?

@PoSayDone
Copy link
Author

PoSayDone commented May 3, 2024

It seems to me that the fact is that the Material Theme Builder does not change the size of the image in any way. Are the colors still incorrect after deleting a line that uses the resize function?

Yes, it still gives the wrong color: #f4bd6f

Also I don't think the image resizing is the problem, because for this image:

wallhaven-qzlzkr

I get a blue primary color, both with and without resizing.

@Aiving
Copy link
Owner

Aiving commented May 4, 2024

Fixed in 0.3.1. However, the colors will still be slightly different from those produced by the Material Theme Builder, since Rust and Dart, for some reason, sometimes give different results when calculating the double-precision floating point number. This is a problem that I cannot solve.

@PoSayDone
Copy link
Author

PoSayDone commented May 6, 2024

Fixed in 0.3.1. However, the colors will still be slightly different from those produced by the Material Theme Builder, since Rust and Dart, for some reason, sometimes give different results when calculating the double-precision floating point number. This is a problem that I cannot solve.

Really sad because all my red wallpapers now has an orange primary color, what didn't happen before

@Aiving
Copy link
Owner

Aiving commented May 8, 2024

@PoSayDone, I think now, in v0.3.2, the issue is completely solved (it seems that my sleepy eyes turned out to be the main issue, because in impl From<Lab> for Argb I used Rgb::new(x, y, z) instead of Xyz::new(x, y, z))

@PoSayDone
Copy link
Author

@PoSayDone, I think now, in v0.3.2, the issue is completely solved (it seems that my sleepy eyes turned out to be the main issue, because in impl From<Lab> for Argb I used Rgb::new(x, y, z) instead of Xyz::new(x, y, z))

Now everything works as expected, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants