end-4 / dots-hyprland

i hate minimalism so...
https://end-4.github.io/dots-hyprland-wiki/en/
GNU General Public License v3.0
3.71k stars 255 forks source link

Wave goodbye to material-color-utilities-python #361

Closed midn8hustlr closed 5 months ago

midn8hustlr commented 5 months ago

Removing dependency material-color-utilities-python in favor of materialyoucolor-python for picking colors from image, as this issue is fixed, and the algorithm is faster too.

end-4 commented 5 months ago

The color generation is faster, but not the color picking?

This PR makes the process for large images much slower. Try setting this very large AI-generated and -upscaled image as wallpaper and you'll see... For me it takes only 1s currently but with this PR it takes 20s

midn8hustlr commented 5 months ago

I haven't tested that for large 4K images. Added image resizing for very large images in c62d771f3855ca939cec85c283dbbaa3abc2f2e4. Please check the latest commit.

T-Dynamos commented 5 months ago

I recommend to have a look at android's compression algorithm:

    // Maximum size that a bitmap can have to keep our calculations valid
    private static final int MAX_BITMAP_SIZE = 112;

    // Even though we have a maximum size, we'll mainly match bitmap sizes
    // using the area instead. This way our comparisons are aspect ratio independent.
    private static final int MAX_WALLPAPER_EXTRACTION_AREA = MAX_BITMAP_SIZE * MAX_BITMAP_SIZE;
        if (bitmapArea > MAX_WALLPAPER_EXTRACTION_AREA) {
            shouldRecycle = true;
            Size optimalSize = calculateOptimalSize(bitmap.getWidth(), bitmap.getHeight());
            bitmap = Bitmap.createScaledBitmap(bitmap, optimalSize.getWidth(),
                    optimalSize.getHeight(), false /* filter */);
        }
    private static Size calculateOptimalSize(int width, int height) {
        // Calculate how big the bitmap needs to be.
        // This avoids unnecessary processing and allocation inside Palette.
        final int requestedArea = width * height;
        double scale = 1;
        if (requestedArea > MAX_WALLPAPER_EXTRACTION_AREA) {
            scale = Math.sqrt(MAX_WALLPAPER_EXTRACTION_AREA / (double) requestedArea);
        }
        int newWidth = (int) (width * scale);
        int newHeight = (int) (height * scale);
        // Dealing with edge cases of the drawable being too wide or too tall.
        // Width or height would end up being 0, in this case we'll set it to 1.
        if (newWidth == 0) {
            newWidth = 1;
        }
        if (newHeight == 0) {
            newHeight = 1;
        }

        return new Size(newWidth, newHeight);
    }

(That bitmap is used for generating colors)

midn8hustlr commented 5 months ago

Hmm, This algorithm is much better, as it will handle any arbitrary image aspect ratio and still ensure that the resized area is always the same. So the compution time is going to be same for any image resolution with any kind of aspect ratio.

The previous algorithm will yield a high bitmap for arbitrary non-standard image aspect ratios (like panaromas).

Perhaps we should always crop the image to the respective screen resolution and then generate colors.

I will consider this algorithm and push a new commit. end-4 dont merge this right now.

Thanks a lot T-Dynamos for the recommendation 💙

midn8hustlr commented 5 months ago

Added new algo in 7d50e437211c1a673de29bf0d6eda44aab0d9c3e You can merge it now

end-4 commented 5 months ago

Performance is good now Thanks for your work!