Skip to content

Commit f48dff0

Browse files
committed
addad svg support
1 parent 88ceb13 commit f48dff0

File tree

3 files changed

+74
-20
lines changed

3 files changed

+74
-20
lines changed

PNG to Icons with GUI/README.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
# PNG to Icon Converter (GUI)
22

3-
A simple Python GUI tool to convert PNG images into icon formats for Windows (.ico), macOS (.icns), and Linux (multiple PNG sizes). Built with PySide6 and Pillow.
3+
A simple Python GUI tool to convert PNG and SVG images into icon formats for Windows (.ico), macOS (.icns), and Linux (multiple PNG sizes). Built with PySide6, Pillow, and CairoSVG.
44

55
---
66

7+
78
## Features
8-
- 🖼️ Select a PNG file and convert it to:
9-
- Windows .ico (16x16, 32x32, 48x48, 256x256)
9+
- 🖼️ Select a PNG or SVG file and convert it to:
10+
- Windows .ico (user-selectable sizes)
1011
- macOS .icns
11-
- Linux PNG icons (16x16 up to 512x512)
12+
- Linux PNG icons (user-selectable sizes)
13+
- ☑️ Checkboxes to select which icon sizes to output
1214
- 📂 Choose output directory
1315
- ⚡ Fast, one-click conversion
1416
- ❌ Error handling with pop-up dialogs
@@ -17,13 +19,15 @@ A simple Python GUI tool to convert PNG images into icon formats for Windows (.i
1719

1820
## Requirements
1921

22+
2023
- Python 3.8+
2124
- PySide6
2225
- Pillow
26+
- CairoSVG (for SVG support)
2327

2428
Install dependencies:
2529
```bash
26-
pip install PySide6 Pillow
30+
pip install PySide6 Pillow cairosvg
2731
```
2832

2933
---
@@ -35,9 +39,9 @@ pip install PySide6 Pillow
3539
python png2icon.py
3640
```
3741
2. Click **"Select PNG and Convert"**
38-
3. Choose a PNG file
42+
3. Choose a PNG or SVG file
3943
4. Select a directory to save the icons
40-
5. Icons for Windows, macOS, and Linux will be created in the chosen folder
44+
5. Icons for Windows, macOS, and Linux will be created in the chosen folder, in the sizes you selected
4145

4246
---
4347

PNG to Icons with GUI/png2icon.py

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,54 @@
11
import sys
22
import os
3-
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QFileDialog, QMessageBox
3+
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QFileDialog, QMessageBox, QCheckBox, QLabel, QHBoxLayout, QGroupBox
44
from PIL import Image
5+
import io
6+
7+
# Pillow 10+ uses Image.Resampling.LANCZOS, fallback for older versions
8+
try:
9+
LANCZOS_RESAMPLE = Image.Resampling.LANCZOS
10+
except AttributeError:
11+
LANCZOS_RESAMPLE = 1 # 1 is the value for LANCZOS in older Pillow
512

613
class IconConverterApp(QWidget):
714
def __init__(self):
815
super().__init__()
9-
self.setWindowTitle("PNG to Icon Converter")
10-
self.setGeometry(200, 200, 300, 120)
16+
self.setWindowTitle("PNG/SVG to Icon Converter")
17+
self.setGeometry(200, 200, 400, 250)
18+
19+
self.sizes = [16, 24, 32, 48, 64, 128, 256, 512]
20+
self.checkboxes = []
21+
22+
# Check SVG support
23+
try:
24+
import cairosvg
25+
self.svg_support = True
26+
except ImportError:
27+
self.svg_support = False
1128

1229
layout = QVBoxLayout()
13-
self.button = QPushButton("Select PNG and Convert")
30+
self.button = QPushButton("Select Image and Convert")
1431
self.button.clicked.connect(self.convert_icon)
1532
layout.addWidget(self.button)
1633

34+
# Add checkboxes for sizes
35+
size_group = QGroupBox("Select icon sizes to output")
36+
size_layout = QHBoxLayout()
37+
for size in self.sizes:
38+
cb = QCheckBox(f"{size}x{size}")
39+
cb.setChecked(True)
40+
self.checkboxes.append(cb)
41+
size_layout.addWidget(cb)
42+
size_group.setLayout(size_layout)
43+
layout.addWidget(size_group)
44+
1745
self.setLayout(layout)
1846

1947
def convert_icon(self):
20-
# Step 1: Select PNG file
21-
png_file, _ = QFileDialog.getOpenFileName(self, "Select PNG File", "", "PNG Files (*.png)")
22-
if not png_file:
48+
# Step 1: Select PNG or SVG file
49+
file_filter = "Image Files (*.png *.svg)" if self.svg_support else "PNG Files (*.png)"
50+
img_file, _ = QFileDialog.getOpenFileName(self, "Select Image File", "", file_filter)
51+
if not img_file:
2352
return
2453

2554
# Step 2: Ask where to save icons
@@ -28,22 +57,42 @@ def convert_icon(self):
2857
return
2958

3059
try:
31-
img = Image.open(png_file).convert("RGBA")
60+
# Load image (handle SVG if needed)
61+
if img_file.lower().endswith('.svg'):
62+
import cairosvg # Ensure cairosvg is in local scope
63+
if not self.svg_support:
64+
QMessageBox.critical(self, "Error", "SVG support requires cairosvg. Please install it.")
65+
return
66+
# Convert SVG to PNG in memory
67+
png_bytes = cairosvg.svg2png(url=img_file)
68+
if png_bytes is None:
69+
raise ValueError("SVG conversion failed.")
70+
img = Image.open(io.BytesIO(png_bytes)).convert("RGBA")
71+
else:
72+
img = Image.open(img_file).convert("RGBA")
73+
74+
# Get selected sizes
75+
selected_sizes = [self.sizes[i] for i, cb in enumerate(self.checkboxes) if cb.isChecked()]
76+
if not selected_sizes:
77+
QMessageBox.warning(self, "No Sizes Selected", "Please select at least one icon size.")
78+
return
3279

3380
# Windows ICO
3481
ico_path = os.path.join(save_dir, "icon.ico")
35-
img.save(ico_path, format="ICO", sizes=[(16,16), (32,32), (48,48), (256,256)])
82+
ico_sizes = [(s, s) for s in selected_sizes if s in [16, 32, 48, 256]]
83+
if ico_sizes:
84+
img.save(ico_path, format="ICO", sizes=ico_sizes)
3685

3786
# macOS ICNS
3887
icns_path = os.path.join(save_dir, "icon.icns")
39-
img.save(icns_path, format="ICNS")
88+
if any(s in [16, 32, 128, 256, 512] for s in selected_sizes):
89+
img.save(icns_path, format="ICNS")
4090

4191
# Linux PNG sizes
42-
linux_sizes = [16, 24, 32, 48, 64, 128, 256, 512]
4392
linux_dir = os.path.join(save_dir, "linux_icons")
4493
os.makedirs(linux_dir, exist_ok=True)
45-
for size in linux_sizes:
46-
resized = img.resize((size, size), Image.LANCZOS)
94+
for size in selected_sizes:
95+
resized = img.resize((size, size), LANCZOS_RESAMPLE)
4796
resized.save(os.path.join(linux_dir, f"icon_{size}x{size}.png"))
4897

4998
QMessageBox.information(self, "Success", f"Icons saved in:\n{save_dir}")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
PySide6
22
Pillow
3+
cairosvg

0 commit comments

Comments
 (0)