mihon icon indicating copy to clipboard operation
mihon copied to clipboard

[FR] Add JXL Compression to Downloaded Images

Open AngelaDMerkel opened this issue 7 months ago • 11 comments

Describe your suggested feature

Mihon already includes JXL support for viewing, and it would be useful to leverage this in order to convert downloaded JPG or PNG images to JXL for some space savings before zipping them up. This makes sense to me for two reasons:

  1. Downloads are scheduled and done overnight while charging, which means any processor or power overhead is likely to be a non-issue.
  2. Storage on a lot of devices is a premium and collecting enough chapters for a read-through can often be limited by remaining space on device. JXL would alleviate this (losslessly).

Other details

No response

Acknowledgements

  • [x] I have searched the existing issues and this is a new ticket, NOT a duplicate or related to another open or closed issue.
  • [x] I have written a short but informative title.
  • [x] I have updated the app to version 0.18.0.
  • [x] I will fill out all of the requested information in this form.

AngelaDMerkel avatar Apr 14 '25 15:04 AngelaDMerkel

Mihon stores exactly what the source provides and I don't think it'd be wise to insert ourselves in this process.

MajorTanya avatar Apr 14 '25 16:04 MajorTanya

I think it's fine to have this as an option

AntsyLich avatar Apr 14 '25 16:04 AntsyLich

  1. Downloads are scheduled and done overnight why charging, which means any processor or power overhead is likely to be a non-issue.
  1. Storage on a lot of devices is a premium and collecting enough chapters for a read-through can often be limited by remaining space on device

I'd be remiss if I didn't point out that both points are subjective.

  1. They're "scheduled" whenever the user sets them. None of my devices is ever charging while I sleep, and my reading tablet is simply powered off while not in use
  2. As it is basically exclusively used for reading, the tablet's native storage is plenty for even more than a full day's worth of backlogged unread chapters.

That said, a separate setting wouldn't hurt

Mihon stores exactly what the source provides and I don't think it'd be wise to insert ourselves in this process.

TBF, it already does by archiving into uncompressed CBZ and splitting tall images :clueless:

BrutuZ avatar Apr 14 '25 22:04 BrutuZ

@BrutuZ Your point is valid, and I meant to imply that while there are options to schedule downloads and limit them to circumstances like wifi connection and charging status, there are also likely to be users who will choose to take the benefit of this as it probably adds no inconvenience.

Your criticism of my second point is not how I use Mihon. I work and travel a lot and allow Mihon to collect series for me and then when I have time I can read through any given series I've picked up. I currently have 200GB saved on my phone. This is (of course) personal preference, but I can't hurt users to have the options.

AngelaDMerkel avatar Apr 15 '25 10:04 AngelaDMerkel

There is already a library that seems capable of doing this, but I haven't used it before so I don't actually know. I have a lot of experience using cjxl compiled on a huge number of systems and architectures and the default effort (7) on lossless provides really good results without significant resource demands at that effort level.

AngelaDMerkel avatar Apr 15 '25 10:04 AngelaDMerkel

If for whatever reason someone wants to do this, this script will convert JPEG and PNG images to JXL and leave the most common animated file types alone:

#!/bin/bash

set -euo pipefail

# Log
LOG_FILE="converted_log.txt"

# Cleanup
cleanup() {
    [[ -n "${TEMP_DIR:-}" && -d "$TEMP_DIR" ]] && rm -rf "$TEMP_DIR"
}
trap cleanup EXIT

# Create the log file if it doesn't exist
touch "$LOG_FILE"

# Process each .cbz file in the current directory and subdirectories
find . -type f -iname "*.cbz" | while read -r CBZ_FILE; do
    [[ -f "$CBZ_FILE" ]] || continue  # Ensure it's a file, not a directory

    ABS_CBZ="$(realpath "$CBZ_FILE")"
    CBZ_DIR="$(dirname "$ABS_CBZ")"
    BASENAME="$(basename "$CBZ_FILE" .cbz)"

    # Skip if this file has already been processed
    if grep -q "$ABS_CBZ" "$LOG_FILE"; then
        echo "⚠️ Skipping (already converted): $CBZ_FILE"
        continue
    fi

    TEMP_DIR="$(mktemp -d)"

    echo "📦 Processing: $CBZ_FILE"

    # Extract CBZ contents
    unzip -q "$CBZ_FILE" -d "$TEMP_DIR"

    # Re-encode eligible images
    find "$TEMP_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) \
        ! -iname "*.webp" ! -iname "*.gif" ! -iname "*.apng" ! -iname "*.avif" ! -iname "*.jxl" | while read -r img; do
        jxl="${img%.*}.jxl"
        echo "🗜️  Converting: $img → $jxl"
        cjxl "$img" "$jxl" -d 0 -e 10
        rm "$img"
    done

    # Create a new CBZ archive
    NEW_CBZ="$CBZ_DIR/$BASENAME.repacked.cbz"
    (cd "$TEMP_DIR" && zip -qr "$NEW_CBZ" .)

    # Replace original file
    mv -f "$NEW_CBZ" "$ABS_CBZ"
    cleanup  # Remove temp dir explicitly here too

    # Log the processed file
    echo "$ABS_CBZ" >> "$LOG_FILE"

    echo "✅ Done: $CBZ_FILE"
done

echo "🎉 All CBZ files in this directory and subdirectories have been processed."

AngelaDMerkel avatar Apr 17 '25 15:04 AngelaDMerkel

Why a bash script for a Kotlin project?

MajorTanya avatar Apr 17 '25 15:04 MajorTanya

It's not meant as a contribution. If anyone wants to do it on Termux or something, they can with this.

AngelaDMerkel avatar Apr 17 '25 17:04 AngelaDMerkel

Related #482

vetleledaal avatar Apr 28 '25 18:04 vetleledaal

@AngelaDMerkel the issue isn't your personal blogpost

AntsyLich avatar May 01 '25 13:05 AntsyLich