Skip to content
This repository has been archived by the owner on Aug 4, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1 from SnowzNZ/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
SnowzNZ authored May 8, 2023
2 parents 710af9c + 1de9151 commit 21972cb
Show file tree
Hide file tree
Showing 7 changed files with 768 additions and 153 deletions.
1 change: 0 additions & 1 deletion FUNDING.yml

This file was deleted.

21 changes: 0 additions & 21 deletions LICENCE.md

This file was deleted.

675 changes: 675 additions & 0 deletions LICENSE.md

Large diffs are not rendered by default.

32 changes: 12 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,20 @@
# HD2SD

<img src="https://media.discordapp.net/attachments/1044134327434358847/1049529615762333716/image.png">

[![CodeFactor](https://www.codefactor.io/repository/github/snowznz/hd2sd/badge)](https://www.codefactor.io/repository/github/snowznz/hd2sd)

High Definition to Standard Definition converter for osu! skins.

Contact: <https://twitter.com/Snowz2k>

I am not responsible for any damage caused to your skins by this program. This can be caused by overwriting files. Make sure to backup any important files before running.
Easily convert @2x (HD) images to SD.

## Usage
- Download the latest executable from the [releases](https://github.com/SnowzNZ/HD2SD/releases/latest).
- Run `HD2SD.exe`.

- Download [latest release](https://github.com/SnowzNZ/HD2SD/releases/latest)

- Run HD2SD.exe
#### Manual Installation
```sh
git clone https://github.com/SnowzNZ/HD2SD
cd HD2SD
pip install -r requirements.txt

- Building from source
py main.py
```

- Download ZIP and extract it or
## License

```sh
git clone https://github.com/SnowzNZ/HD2SD
cd HD2SD
pip install -r requirements.txt
pyinstaller --noconfirm --onefile --windowed --add-data "%localappdata%/Programs/Python/Python311/Lib/site-packages/customtkinter;customtkinter/" "main.py"
```
This project is licensed under the GPL-3.0 License - see the [LICENSE.md](https://github.com/SnowzNZ/HD2SD/blob/main/LICENCE.md) file for details
10 changes: 10 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# HD2SD Planned Features


### Todo

- [ ] Add option to change Resampling algorithm
- [ ] Add option to change downscale/upscale size
- [ ] Ask if the user wishes to overwrite existing SD images
- [ ] Add option to include sub-directories
- [ ] Add GitHub Actions workflow for pyinstaller
176 changes: 68 additions & 108 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,119 +1,79 @@
"""
Program to convert HD images to SD
Create SD images for osu! skins by downscaling HD images by 50%
"""

import glob
import threading
from tkinter import filedialog, messagebox
import os
import textwrap
import time
from tkinter import filedialog

import customtkinter # type: ignore
import readchar
from pick import pick
from PIL import Image

customtkinter.set_appearance_mode("System")
customtkinter.set_default_color_theme("blue")


class App(customtkinter.CTk):
"""GUI"""

WIDTH = 350
HEIGHT = 200

def __init__(self):
super().__init__()

self.title("HD2SD")
self.geometry(f"{App.WIDTH}x{App.HEIGHT}")
self.protocol("WM_DELETE_WINDOW", self.on_closing)
self.resizable(False, False)
self.filename = None

self.button_folder = customtkinter.CTkButton(
master=self,
width=250,
height=30,
border_width=0,
corner_radius=30,
text="Select Skin Folder",
command=self.select_folder,
text_color_disabled="#000",
)
self.button_folder.place(
relx=0.5, rely=0.2, anchor=customtkinter.CENTER
)

self.entry = customtkinter.CTkEntry(
master=self, placeholder_text="", state="disabled", width=250
)
self.entry.place(relx=0.5, rely=0.35, anchor=customtkinter.CENTER)

self.button_convert = customtkinter.CTkButton(
master=self,
width=250,
height=30,
border_width=0,
corner_radius=30,
text="Convert!",
command=self.start_convert,
)
self.button_convert.place(
relx=0.5, rely=0.62, anchor=customtkinter.CENTER
)
self.button_convert.configure(state="disabled")

self.progressbar = customtkinter.CTkProgressBar(master=self, width=250)
self.progressbar.place(
relx=0.5, rely=0.73, anchor=customtkinter.CENTER
)
self.progressbar.set(0)

def start_convert(self):
"""Start the convert function"""
threading.Thread(target=self.convert).start()
self.progressbar.set(0)

def convert(self):
"""Convert all @2x images to SD"""
images_converted = 0
confirm = messagebox.askquestion(
"HD2SD", "Are you sure you want to convert your HD files to SD?"
)
if confirm == "yes":
hd_images = glob.glob(rf"{self.filename}/*@2x.png")

for i in hd_images:
images_converted += 1
progress = images_converted / len(hd_images)
hd_image = Image.open(i)
x_pos, y_pos = hd_image.size
if x_pos >= 2 and y_pos >= 2:
size = (x_pos // 2, y_pos // 2)
else:
size = (x_pos, y_pos)
hd_image = hd_image.resize(size, Image.Resampling.LANCZOS)
name = i.split("@")
hd_image.save(f"{name}.png")
self.progressbar.set(progress)
messagebox.showinfo("HD2SD", "Conversion Complete!")
from tqdm import tqdm

print(
"""
HD2SD Copyright (C) 2023 SnowzNZ
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions.
"""
)

# Default location for osu! skins
default_skin_path = os.path.join(os.environ["LOCALAPPDATA"], "osu!", "Skins")

# Check if the path exists
if os.path.exists(default_skin_path):
folder_path = filedialog.askdirectory(initialdir=default_skin_path)
else:
folder_path = filedialog.askdirectory()

# Ask the user if they wish to continue
option, _ = pick(
["Yes", "No"],
textwrap.fill(f"Selected Folder: {folder_path}")
+ "\n\nAre you sure you wish to continue?",
)

if option == "Yes":
# Get start time of process
start_time = time.time()

# Get every image in the folder
for image in tqdm(
glob.glob(rf"{folder_path}/*@2x.png"),
desc="Converting images to SD",
unit=" image",
):
# Open the HD image
hd_image = Image.open(image)

# Get the width and height of the image
width, height = hd_image.size

# Check if the image is more than 1x1
# If not, break out of the for loop as 1/2 != a whole number
if width > 1 and height > 1:
size = (width // 2, height // 2)
else:
pass
continue

# Resize the image
hd_image = hd_image.resize(size, Image.Resampling.LANCZOS)
# Save the image as an SD image
hd_image.save(image.replace("@2x", ""))

def select_folder(self):
"""Choose folder to convert"""
self.filename = filedialog.askdirectory()
self.button_convert.configure(state="normal")
self.entry.configure(
state="normal", placeholder_text=self.filename.split("Skins/")[1]
)
self.entry.configure(state="disabled")
self.button_folder.configure(text="Change Skin Folder")
self.progressbar.set(0)
# Get end time of process
end_time = time.time()

def on_closing(self):
"""Destroy window on close"""
self.destroy()
# Calculate total time it took
elapsed_time = end_time - start_time

# Print total time it took to complete
print(f"\nCompleted in {round(elapsed_time, 3)} seconds.")

if __name__ == "__main__":
app = App()
app.mainloop()
print("Press any key to exit...")
key = readchar.readkey()
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
tqdm
pillow
customtkinter
tk
types-Pillow
pick
readchar

0 comments on commit 21972cb

Please sign in to comment.